【问题标题】:Alternative to Collectors.groupingBy() for scalascala 的 Collectors.groupingBy() 替代方案
【发布时间】:2015-02-19 15:13:13
【问题描述】:

在 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)]

【问题讨论】:

    标签: java scala collectors


    【解决方案1】:

    Java lambda 是任意函数接口的“实现者”(在这种特殊情况下,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 =&gt; 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
    

    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
    

    【讨论】:

    • 发现问题,groupingBy后需要[Re, java.lang.String]
    • 我的意思是您的更新很有帮助,而不是我自己发现的:D
    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 2021-12-22
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多