英文:
Why Comparable and Comparator are consumers in PECS wildcard types in Java
问题
在《Effective Java》中,在项目“使用有界通配符以增加API的灵活性”中,当讨论PECS(生产者-扩展,消费者-超级)的使用时,作者提到:
> Comparables始终是消费者,因此通常应首选使用Comparable<? super T>而不是Comparable<T>。比较器也是如此;因此,通常应首选使用Comparator<? super T>而不是Comparator<T>。
我不清楚为什么Comparables和Comparators被认为是消费者。
在讨论PECS的一个主题中,https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super,消费者通常是指将Collection作为某个通用方法的参数。
而在这里,Comparable只是一个接口。
有人能分享一些见解吗?谢谢!
英文:
In Effective Java, in the item "Use bounded wildcards to increase API flexibility", when talking about the usage of PECS (producer-extends, consumer-super), the author mentioned that:
> Comparables are always consumers, so you should generally use Comparable<? super T> in preference to Comparable<T>. The same is true of comparators; therefore, you should generally use Comparator<? super T> in preference to Comparator<T>.
It is not clear to me why Comparables and Comparators are considered consumers.
In one of the topic discussing PECS, https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super, the consumer is usually referring to a Collection as a parameter for some generic method.
While here Comparable is just an interface.
Can anyone share some insights? Thanks!
答案1
得分: 5
以下是翻译好的部分:
一个很好的类比可以与接口 Consumer<T>
和 Supplier<T>
进行。(Supplier
类似于生产者)。Consumer<T>
是一个接受 T
的函数,而 Supplier<T>
是一个返回 T
的函数。请注意,我们谈论的是方法签名和返回类型,我们没有涉及方法的语义。这是PECS的核心属性:它与语义无关,完全可以根据所使用的方法的签名和返回类型来确定。
观察 Comparable<T>
和 Comparator<T>
,我们发现两者都有方法 (int compareTo(T)
和 int compare(T, T)
),这些方法接受,即消耗 T
的实例。
对于集合,我们必须看我们如何使用集合,即是否使用生成器方法或消费器方法:
- 如果我们从集合中检索数据(
T get(int)
,迭代器等),列表为我们生成值,我们使用? extends T
。 - 如果我们使用集合来存储数据(即我们调用
add(T)
,addAll(Collection<T>)
,contains(T)
等),我们调用消费方法,因此该方法是我们数据的消费者,我们使用? super T
。 - 如果我们使用集合既用于存储又用于检索值,那么集合同时充当生产者和消费者,因此我们必须使用精确的
T
,既不使用... extends ...
也不使用... super ...
。
英文:
A nice analogy can be drawn to the interfaces Consumer<T>
and Supplier<T>
(with Supplier
being analogous to Producer). A Consumer<T>
is a function that takes in a T
, while a Supplier<T>
is a function that returns a T
. Notice that we are talking about method signatures and return type, we say nothing about the semantics of the method. This is a core property of PECS: it is independent of the semantics and can be determined solely on the signature and return type of the methods used.
Looking at Comparable<T>
and Comparator<T>
, we find that both have methods (int compareTo(T)
and int compare(T, T)
) that take in, i.e. consume, T
's.
For the collections, we have to look on how we use the collection, i.e. if we are using producer- or consumer-methods:
- If we retrieve data from the collection (
T get(int)
, iterator, ...), the list produces values for us and we use? extends T
. - If we use the collection to store data, (i.e. we call
add(T)
,addAll(Collection<T>)
,contains(T)
, ...), we call consuming methods, thus the method is a consumer of our data and we use? super T
. - If we use a collection to both store and retrieve values, the collection acts as a consumer and producer at the same time, thus we have to use the precise
T
, neither using... extends ...
nor... super ...
.
答案2
得分: 3
"不清楚为什么可比较对象(Comparables)和比较器(Comparators)被认为是消费者。"
每当泛型类C
因此,Comparator
英文:
> „…It is not clear to me why Comparables and Comparators are considered consumers.…“
Anytime a method member of a generic class C<T>
, takes in (i.e. „consumes“) an argument that is of type T
, then that method is a consumer of T
s.
So Comparator<T>.compareTo(T o)
is said to be a „consumer“ of the o
object of the type represented by the type variable T
.
答案3
得分: 3
当我们说“Comparable
是一个消费者”时,实际上是指“接口的方法是一个消费者”。这是回答你对“Comparable
只是一个接口”的疑问的答案。
查看其签名:https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Comparable.html#compareTo(T)
int compareTo(T o)
它消费泛型 T
,不生成任何泛型对象。
英文:
When we say "Comparable
is a consumer", we actually mean "the method of the interface is a consumer". This is an answer to your doubt that "Comparable
is just an interface."
See its signature: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Comparable.html#compareTo(T)
int compareTo(T o)
It consumes the generic T
, it does not produce any generic object.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论