首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非集合中泛型的PECS

非集合中泛型的PECS
EN

Stack Overflow用户
提问于 2019-02-07 22:45:11
回答 1查看 222关注 0票数 2

约书亚·布洛赫提出了PECS,规定了何时使用? extends T? super T的规则。如果你从Collections框架的角度来考虑PECS,那么它是非常简单的。如果向数据结构添加值,请使用? super T。如果从数据结构中读取,请使用? extends T。例如:

代码语言:javascript
复制
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));   
    }   
}

如果我检查签名

代码语言:javascript
复制
public static <T> void sort(List<T> list, Comparator<? super T> c) 

我看到比较器使用? super,所以它应该是一个消费者。看一下代码,比较器c只用来产生东西,因为它被问到比较的逻辑。

一方面,我理解它为什么是超级的,因为作为一个开发人员,我想使用T类的比较器和超类T的比较器,因为T的对象也是T的超类类型。但当我试图从PECS的角度思考时,我无法理解。

PECS是否仅适用于集合框架?如果没有,谁能向我解释一下比较程序在Collections.sort中使用的是什么?

EN

回答 1

Stack Overflow用户

发布于 2019-02-08 02:56:43

为了回答这个问题,让我们将Comparator作为主要的指导性示例。

如果仔细考虑,您会发现Comparator实际上是接收两个类型为T的参数,并返回它们比较的结果(用int表示)。换句话说,它使用两个T类型的实例并生成一个int值。因此,根据PECS规则,它是T的消费者,因此使用? super T

更一般地,您应该从主类型的角度考虑生产者和消费者,这与其每个泛型参数的类型有关。如果某个Comparator类型使用类型为T的对象,则PECS规则规定该Comparator<T>的用户可以使用它来比较其类型为T的子类型的对象。

作为一个具体的例子,如果你碰巧已经有了比较两个通用Number实例的逻辑(不管它们的具体类型实际上是什么),你可以用它来比较Double实例,因为doubles毕竟是数字。

考虑下面的比较器:

代码语言:javascript
复制
Comparator<Number> c = Comparator.comparingInt(Number::intValue);

在这里,比较器c通过只考虑Number实例的整体部分来比较它们(任意数量)。

如果您有以下Double实例列表:

代码语言:javascript
复制
List<Double> doubles = Arrays.asList(2.2, 2.1, 7.3, 0.2, 8.4, 9.5, 3.8);

和下面的sort方法:

代码语言:javascript
复制
static <T> void sort(List<T> list, Comparator<T> c) {
    list.sort(c);
}

(请注意,Comparator参数中没有通配符? super T )。

然后,如果您想对List<Double> doubles列表进行排序,上面的sort方法的签名将要求您传递一个具体的Comparator<Double>。但是,如果您希望使用先前定义的c比较器对List<Double> doubles进行排序,该怎么办?

由于该比较器的类型为Comparator<Number>,而doubles列表的类型为List<Double>,因此以下代码将产生编译错误:

代码语言:javascript
复制
sort(doubles, c);

幸运的是,由于Comparator是它所比较的元素类型的使用者,您可以将sort方法的签名更改为:

代码语言:javascript
复制
static <T> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

现在,这段代码将会编译:

代码语言:javascript
复制
sort(doubles, c);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54575889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档