将通用通配符从Java转换为Scala

将通用通配符从Java转换为Scala,java,scala,generics,Java,Scala,Generics,在java.util.Collections类中,我们有两种排序方法的变体,一种是使用相应的比较器获取任意对象的列表: public static <T> void sort(List<T> list, Comparator<? super T> comparator) 我在想如何将这种带有有界通配符的方法签名转换成Scala。对于第一版,我将签名逐字翻译,一目了然,没有编译问题: def sort[T](list: List[T], comparator

java.util.Collections
类中,我们有两种
排序
方法的变体,一种是使用相应的
比较器获取任意对象的列表

public static <T> void sort(List<T> list, Comparator<? super T> comparator)

我在想如何将这种带有有界通配符的方法签名转换成Scala。对于第一版,我将签名逐字翻译,一目了然,没有编译问题:

def sort[T](list: List[T], comparator: Comparator[_ >: T]) { ??? }
但后来我发现我无法使用以下参数调用此方法:

val comparator = new Comparator[Object] {
    def compare(o1: Object, o2: Object) = ???
}
val list = new ArrayList[Number]
sort[Object](list, comparator)
最后一行给出了这个编译错误,即使我将类型
T
明确指定为
对象


类型失配;找到:java.util.ArrayList[Number]必需:java.util.List[Object]注意:Number您为
T
提供了错误的类型参数:您排序的是
列表[Number]
,而不是
列表[Object]

sort[Number](list, comparator)
会有用的

如果要在不使用类型参数的情况下调用sort,则需要定义两个参数列表(因为类型推断在Scala中是如何工作的):

您可能想考虑使用Scala类型,它有适当的协方差支持(即在斯卡拉A <代码>列表[No] >是<代码>列表[Obj] < /C> > 关于comparable的版本,您必须显式地编写通配符:

def sort[T <: Comparable[T], U <: T](list: List[U]) { ??? }

def sort[T您可以使用以下命令调用Java变体(或您的变体):

这里的问题是因为Java泛型类型是不变的。换句话说,这在Java中失败了:

List<Number> l1;
List<Integer> l2 = l1; //contravariance fails
List<Object> l3 = l1; //covariance fails

但是因为您使用的是Java的
Java.util.List
,所以这不是一个选项。

啊,对了,我现在看到了错误!即使在Java中,客户端代码也需要是
Collections.sort(List,comparator)
,而不是
Collections.sort(List,comparator)
。另外,关于拆分参数列表的一个很好的注意事项,我不知道!你能详细说明一下
Compariable
列表的版本吗?将通配符拆分为两个类型参数的有趣方法,但似乎是正确的。谢谢。@Natix我认为你不能像以前那样使用通配符,因为类型搜索(对于
\U
)可能会出现分歧。在具有两个参数的版本中,我们将依赖项从
T
(前
\U
)移除到
U
。对于
可比的
版本,
定义排序之间的区别是什么[T啊,是的,我现在看到了错误!即使在Java中,客户端代码也需要是
集合。sort(list,comparator)
,而不是
集合。sort(list,comparator)
。你能详细说明一下
Comparable
列表的版本吗?顺便说一句,我认为Scala的列表类型参数实际上是协变的(
List[+A]
)。@Natix:我希望我能回答你关于类似情况的问题。我最近刚从Java被介绍到Scala,你所拥有的与我在Java中所做的完全相同(事实上,这是真正的实现所做的)。要求第二个类型参数似乎是完全过火了。
sort[Number](list, comparator)
def sort[T](list: List[T])(comparator: Comparator[_ >: T]) { ??? }

// Then
sort(list)(comparator)
def sort[T <: Comparable[T], U <: T](list: List[U]) { ??? }
Collections.sort[Number](list, comparator)
List<Number> l1;
List<Integer> l2 = l1; //contravariance fails
List<Object> l3 = l1; //covariance fails
val l1: List[Number] = ???
val l2: List[Object] = l1 //valid