为什么 Comparable 和 Comparator 是 Java 中 PECS 通配符类型的消费者

cxs*_*031 3 java generics super pecs

在Effective Java中,在“使用有界通配符增加API灵活性”一文中,在谈到PECS(producer-extends,consumer-super)的使用时,作者提到:

Comparable 始终是消费者,因此您通常应该使用 Comparable<? super T> 优先于 Comparable。比较器也是如此;因此,您通常应该使用 Comparator<? super T> 优先于比较器。

我不清楚为什么 Comparables 和 Comparator 被认为是消费者。

在讨论 PECS 的主题之一中,什么是 PECS(生产者扩展消费者超级)?,消费者通常将 Collection 称为某个泛型方法的参数。

而这里 Comparable 只是一个接口。

任何人都可以分享一些见解吗?谢谢!

Tur*_*g85 5

可以对接口Consumer<T>Supplier<T>Supplier类似于生产者)进行一个很好的类比。AConsumer<T>是一个接受 a 的函数T,而 aSupplier<T>是一个返回 a 的函数T。请注意,我们在谈论方法签名和返回类型,我们没有提及方法的语义。这是 PECS 的一个核心属性:它独立于语义并且可以仅根据所使用方法的签名和返回类型来确定。

查看Comparable<T>and Comparator<T>,我们发现两者都有方法 ( int compareTo(T)and int compare(T, T)) 接受,即消耗, T's。

对于集合,我们必须查看我们如何使用集合,即我们使用的是生产者方法还是消费者方法:

  • 如果我们从集合 ( T get(int), iterator, ...) 中检索数据,列表为我们生成值,我们使用? extends T.
  • 如果我们使用集合来存储数据,(即我们调用add(T), addAll(Collection<T>), contains(T), ...),我们调用消费方法,因此该方法是我们数据的消费者,我们使用? super T.
  • 如果我们使用集合来存储和检索值,则集合同时充当消费者和生产者,因此我们必须使用精确的T,既不使用... extends ...也不使用... super ...