Альтернатива Collectors.groupingBy () для scala

1

В Java у меня есть что-то вроде:

Collectors.groupingBy((Re r) -> return r.pName)

И он работает правильно. Теперь я пытаюсь сделать то же самое в scala, например:

Collectors.groupingBy((r:Re) => return r.pName)

но потом я получаю такие вещи, как

cannot resolve reference groupingBy with such signature
cannot resolve symbol groupingBy

unspecified value parameters Collector
unspecified value parameters Supplier

Дайте мне знать, если вам нужна дополнительная информация/код, и я создам некоторый фиктивный пример, так как мне не разрешено публиковать точный код.

Обновление, основанное на ответе Владимира Матвеева:

pName должен быть String, но если я напишу new java.util.function.Function[Re, java.lang.String] тогда я получу

type mismatch;
 found   : java.util.function.Function[Re,String]
 required: java.util.function.Function[_ >: Re, _ <: ?0(in value x$1)(in value x$1)(in value x$1)(in value x$1)]
Теги:
collectors

1 ответ

3
Лучший ответ

Java lambdas являются "разработчиками" произвольных функциональных интерфейсов (в этом конкретном случае Collectors.groupingBy() принимает java.util.function.Function. Анонимные функции Scala, однако, являются экземплярами некоторого класса, реализующего свойство scala.FunctionX. Следовательно, вы можете Использовать функции Scala для произвольных функциональных интерфейсов (но, как я знаю, есть планы, чтобы это разрешить).

Вам необходимо создать анонимный класс, расширяющий java.util.function.Function:

Collectors.groupingBy(new java.util.function.Function[Re, ???] {
  def apply(r: Re) = r.pName
})

(вам нужно поставить правильный тип pName вместо ???, конечно).

Если вы часто это делаете, вы можете определить неявное преобразование для Scala T => U в java.util.function.Function[T, U]:

implicit class FunctionWrapper[T, U](f: T => U) extends java.util.function.Function[T, U] {
  def apply(x: T): U = f(x)
}

Затем (учитывая, что это неявно находится в области видимости), вы можете использовать его, как вы пытались на начальном этапе:

Collectors.groupingBy((r: Re) => r.pName)

Обновление Я понятия не имею, почему происходит ваша ошибка (возможно, из-за некоторых несовместимостей между Scala и Java generics), но если вы укажете все типы явно, это сработает:

scala> Collectors.groupingBy[Re, String](new JFunction[Re, String] {
     |   def apply(r: Re) = r.pName
     | })
res2: java.util.stream.Collector[Re, _, java.util.Map[String,java.util.List[Re]]] = java.util.stream.Collectors$CollectorImpl@4f83df68

(JFunction - это псевдоним для функции java.util.function.Function).

Вариант с неявным адаптером выглядит лучше (но все еще требует явных аннотаций типа):

scala> Collectors.groupingBy[Re, String]((r: Re) => r.pName)
res4: java.util.stream.Collector[Re, _, java.util.Map[String,java.util.List[Re]]] = java.util.stream.Collectors$CollectorImpl@71075444
  • 0
    пожалуйста, смотрите обновление. Любая идея, что он хочет?
  • 0
    @ KKO, пожалуйста, смотрите мое обновление
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню