Scala resolving to wrong override in Comparator.thenComparing

心不动则不痛 提交于 2020-01-03 09:05:10

问题


I'm trying to translate the following Java code:

import java.util.Comparator;

public class ComparatorTestJava {
    public static void test() {
        Comparator<String> cmp = (s1, s2) -> 0;
        cmp = cmp.thenComparing(s -> s);
    }
}

into Scala. I think this should work:

import java.util.{Comparator, function}

object ComparatorTest {
  var comparator: Comparator[String] = (t1, t2) ⇒ 0
  comparator = comparator.thenComparing(new function.Function[String, String] {
    override def apply(t: String): String = t
  })
}

But it fails with the following error:

Error:(7, 41) type mismatch;
 found   : java.util.function.Function[String,String]
 required: java.util.Comparator[? >: String]
  comparator = comparator.thenComparing(new function.Function[String, String] {

It looks like the Scala compiler is convinced I'm trying to use thenComparing(Comparator) instead of thenComparing(Function). Is there any way I can tell it which it is? Or is that actually not the issue?

(I realize there are other, perhaps more idiomatic, ways to do build a comparator in Scala, but I'm interested in understanding why this fails.)


回答1:


Given the definitions

val comparator: Comparator[String] = (t1, t2) => 0
val f: function.Function[String, String] = s => s

the following fails with the same error as in your question:

comparator.thenComparing(f)

but this compiles successfully:

comparator.thenComparing[String](f)

This is a very common type of errors that occur regularly whenever one tries to use generic Java interfaces from Scala. The reason is that Java's use-site variance does not play well with Scala's declaration-site variance, so that Java's Comparator<? super T> translates into a wildcard type Comparator[_ >: T], and it somehow confuses the type inference algorithm (especially if you combine it with overloaded methods and SAM). However, once recognized, the problem is very easily solved by specifying the type parameters explicitly, in this case, adding an explicit [String] is enough.



来源:https://stackoverflow.com/questions/54609769/scala-resolving-to-wrong-override-in-comparator-thencomparing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!