在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应该是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)]
答案 0 :(得分: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泛型之间存在一些不兼容性),但是如果明确指定所有类型它确实有效:
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