我有以下Scala代码:
import java.util.{Comparator, function}
object ComparatorTest {
Comparator.comparing[Int, String](new function.Function[Int, String] {
override def apply(t: Int): String = t.toString
})
}
Run Code Online (Sandbox Code Playgroud)
编译没有问题.我想我应该能够Function用lambda 替换它(这是我从文档中理解的,至少,IntelliJ是相同的意见).但是,当我用它替换它
Comparator.comparing[Int, String]((t: Int) ? t.toString)
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误:
Error:(6, 23) overloaded method value comparing with alternatives:
(x$1: java.util.function.Function[_ >: Int, _ <: String])java.util.Comparator[Int] <and>
(x$1: java.util.function.Function[_ >: Int, _ <: String],x$2: java.util.Comparator[_ >: String])java.util.Comparator[Int]
cannot be applied to (Int => String)
Comparator.comparing[Int, String]((t: Int) ? t.toString)
Run Code Online (Sandbox Code Playgroud)
(在我看来,第一种选择应该匹配.)
我刚刚问了一个类似的问题,解决方法是明确指定类型参数,但在这种情况下,我认为我已经指定了我能做的一切.是否有另一种使用lambda的解决方案,或者是否需要明确Function需要?如果是后者,是否有一个文档解释了什么时候lambda可以替代SAM?
TL; DR:使用Ordering而不是Comparator直接使用.
您可以使用类型归属来强制它将您的参数识别为java.util.function.Function[Int, String]:
Comparator.comparing[Int, String]((_.toString) : function.Function[Int, String])
Run Code Online (Sandbox Code Playgroud)
请注意,周围的括号_.toString是必需的; 否则,它会尝试将ascription应用于lambda中的表达式而不是lambda作为整体.此代码基本上等同于:
val tmp: function.Function[Int, String] = _.toString
Comparator.comparing[Int, String](tmp)
Run Code Online (Sandbox Code Playgroud)
但是,在编写Scala时,通常更好用Ordering.自Ordering扩展以来Comparator,它可以在任何Comparator预期的地方使用.您可以使用它:
val cmp: Comparator[Int] = Ordering.by(_.toString)
Run Code Online (Sandbox Code Playgroud)
要么:
val cmp = Ordering.by[Int, String](_.toString)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,类型推断在这里工作得更好.
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |