佩奇在非泛型集合

问题描述 投票:1回答:1

约书亚布洛赫想出了佩奇,它说规则时使用?扩展T和?超级T.如果你想在佩奇集合框架方面,那么它是非常简单的。如果添加值的数据结构,使用?超级T.如果从数据结构中读取,使用?扩展T.例如:

public class Collections {  
    public static <T> void copy(List<? super T> dest, List<? extends T> src) {  
        for (int i = 0; i < src.size(); i++)   
            dest.set(i, src.get(i));   
    }   
}

如果我检查的签名

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

我看到的比较器使用?超好,所以它应该是消费者。看代码,比较C仅使用,因为它被要求比较的逻辑产生的东西。

一方面,我明白为什么它是一个超级因为作为一个开发者,我想用T级的比较器和比较器也超级T级的,因为T的对象的类型为超类T的也不过当我尝试去思考佩奇而言,我不明白。

难道只有佩奇持有集合框架?如果没有,就有人向我解释什么比较的Collections.sort消费?

java generics collections bounded-wildcard
1个回答
3
投票

对于这个答案的缘故,让我们Comparator为主体,指导例子。

如果你仔细想想,你会看到Comparator实际收到类型T的两个参数,并返回它们的比较(由int表示)的结果。换句话说,它消耗型T的两个实例,并产生int值。所以,作为由PECS规则,它是一个消费T的,因此,使用? super T的。

更一般地,你应该看的主要类型的相对于它的类型泛型参数中的每一个点考虑生产者和消费者。如果某些Comparator型消费型T的对象时,佩奇规则规定,这种Comparator<T>的用户可以用它来比较的对象,其类型为T的亚型。

作为一个具体的例子,如果你碰巧已经有了比较两个通用Number实例(无论其具体类型实际上是)的逻辑,你可以使用它即比较Double情况下,因为双打的数字,毕竟。

请看下面的比较:

Comparator<Number> c = Comparator.comparingInt(Number::intValue);

这里,比较器c通过仅考虑它们的组成部分相比较Number实例(任何数量)。

如果你有Double实例如下列表:

List<Double> doubles = Arrays.asList(2.2, 2.1, 7.3, 0.2, 8.4, 9.5, 3.8);

而下面的sort方法:

static <T> void sort(List<T> list, Comparator<T> c) {
    list.sort(c);
}

(注意在? super T参数不存在通配符Comparator的)。

然后,如果要排序的List<Double> doubles名单,上面sort方法的签名会要求你通过一个具体的Comparator<Double>。但是,如果你想使用先前定义的c比较排序的List<Double> doubles什么?

作为比较的类型是Comparator<Number>,并作为doubles列表的类型是List<Double>,下面的代码会产生一个编译错误:

sort(doubles, c);

幸运的是,Comparator是比较元素类型的消费者,你可以改变sort方法的签名:

static <T> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

而现在,这样的代码将编译:

sort(doubles, c);
© www.soinside.com 2019 - 2024. All rights reserved.