2

在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

如果您需要更多信息/代码,请告诉我,我将创建一些虚拟示例,因为我不允许发布确切的代码。

基于@Vladimir Matveev 回答的更新:

pName 应该是字符串,但如果我写,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)]
4

1 回答 1

3

Java lambda 是任意函数接口的“实现者”(在这种特殊情况下Collectors.groupingBy()接受java.util.function.Function.Scala 匿名函数,但是,是某些实现scala.FunctionXtrait 的类的实例。因此,您不能将 Scala 函数用于任意函数接口(但有计划据我所知,允许这样做)。

您需要创建一个java.util.function.Function显式扩展的匿名类:

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

(当然,您需要输入正确的类型 ofpName而不是???)。

如果您经常这样做,您可以为 Scala 定义一个隐式转换T => Uto 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 泛型之间的一些不兼容),但是如果您明确指定所有类型,它确实有效:

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

(JFunctionjava.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
于 2015-02-19T15:41:29.910 回答