Collections.max 方法类型参数声明签名 <T extends Comparable<? super T>> 说明
Collections.max method type parameters declaration signature <T extends Comparable<? super T>> explanation
在 Naftalin 和 wadler 的 Java Generics 第 3 章 comparison and Bounds 中,它以 Collections.max 方法为
<T extends Comparable<? super T>> T max(Collection<? extends T> coll)
和
<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
第二个签名在 Java api 中(为了向后兼容)。
根据 Get -put 原则,我理解 Producer extends 和 consumer super .
现举例如下:
abstract class Fruit {
protected String name;
protected int size;
protected Fruit(String name, int size) {
this.name = name; this.size = size;
}
public boolean equals(Object o) {
if (o instanceof Fruit) {
Fruit that = (Fruit)o;
return this.name.equals(that.name) && this.size == that.size;
} else return false;
}
public int hashCode() {
return name.hashCode()*29 + size;
}
protected int compareTo(Fruit that) {
return this.size < that.size ? -1 :
this.size == that.size ? 0 : 1 ;
}
}
class Apple extends Fruit implements Comparable<Apple> {
public Apple(int size) {
super("Apple", size);
}
public int compareTo(Apple a) {
return super.compareTo(a);
}
}
class Orange extends Fruit implements Comparable<Orange> {
public Orange(int size) {
super("Orange", size);
}
public int compareTo(Orange o) {
return super.compareTo(o);
}
}
class Test {
public static void main(String[] args) {
Apple a1 = new Apple(1);
Apple a2 = new Apple(2);
Orange o3 = new Orange(3);
Orange o4 = new Orange(4);
List<Apple> apples = Arrays.asList(a1,a2);
assert Collections.max(apples).equals(a2);
List<Orange> oranges = Arrays.asList(o3,o4);
assert Collections.max(oranges).equals(o4);
List<Fruit> mixed = Arrays.<Fruit>asList(a1,o3);
assert Collections.max(mixed).equals(o3); // compile-time error
}
}
现在它说:
这个例子说明了为什么需要这个通配符。如果我们想比较两个
橙子,我们把上面代码中的T取为Orange:
Orange extends Comparable<? super Orange>
这是真的,因为以下两项都成立:
Orange extends Comparable<Fruit> and Fruit super Orange
如果没有超级通配符,查找 List<Orange>
的最大值将是非法的,
即使允许找到 List<Fruit>
的最大值
我确实理解这个例子中的所有内容,除了行 如果没有超级通配符,找到 List<Orange>
的最大值将是非法的
我发现自己处境不明。然而,我在 Whosebug 上得到了很多解释 Collections.max 方法签名的答案(我确实理解该签名,可能不完全)。
你错误地引用了这本书。该声明是关于 Fruit implements Comparable<Fruit>
的情况。在这种情况下,Orange
将不是 <T extends Comparable<T>>
的有效候选者,因为 Orange
没有实现 Comparable<Orange>
。因此,您不能将 List<Orange>
作为 List<T>
传递,除非 <T extends Comparable<? super T>>
,这确保可以通过 Fruit
超类将一个 Orange
与另一个进行比较.
在 Naftalin 和 wadler 的 Java Generics 第 3 章 comparison and Bounds 中,它以 Collections.max 方法为
<T extends Comparable<? super T>> T max(Collection<? extends T> coll)
和
<T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
第二个签名在 Java api 中(为了向后兼容)。
根据 Get -put 原则,我理解 Producer extends 和 consumer super .
现举例如下:
abstract class Fruit {
protected String name;
protected int size;
protected Fruit(String name, int size) {
this.name = name; this.size = size;
}
public boolean equals(Object o) {
if (o instanceof Fruit) {
Fruit that = (Fruit)o;
return this.name.equals(that.name) && this.size == that.size;
} else return false;
}
public int hashCode() {
return name.hashCode()*29 + size;
}
protected int compareTo(Fruit that) {
return this.size < that.size ? -1 :
this.size == that.size ? 0 : 1 ;
}
}
class Apple extends Fruit implements Comparable<Apple> {
public Apple(int size) {
super("Apple", size);
}
public int compareTo(Apple a) {
return super.compareTo(a);
}
}
class Orange extends Fruit implements Comparable<Orange> {
public Orange(int size) {
super("Orange", size);
}
public int compareTo(Orange o) {
return super.compareTo(o);
}
}
class Test {
public static void main(String[] args) {
Apple a1 = new Apple(1);
Apple a2 = new Apple(2);
Orange o3 = new Orange(3);
Orange o4 = new Orange(4);
List<Apple> apples = Arrays.asList(a1,a2);
assert Collections.max(apples).equals(a2);
List<Orange> oranges = Arrays.asList(o3,o4);
assert Collections.max(oranges).equals(o4);
List<Fruit> mixed = Arrays.<Fruit>asList(a1,o3);
assert Collections.max(mixed).equals(o3); // compile-time error
}
}
现在它说:
这个例子说明了为什么需要这个通配符。如果我们想比较两个 橙子,我们把上面代码中的T取为Orange:
Orange extends Comparable<? super Orange>
这是真的,因为以下两项都成立:
Orange extends Comparable<Fruit> and Fruit super Orange
如果没有超级通配符,查找 List<Orange>
的最大值将是非法的,
即使允许找到 List<Fruit>
的最大值
我确实理解这个例子中的所有内容,除了行 如果没有超级通配符,找到 List<Orange>
的最大值将是非法的
我发现自己处境不明。然而,我在 Whosebug 上得到了很多解释 Collections.max 方法签名的答案(我确实理解该签名,可能不完全)。
你错误地引用了这本书。该声明是关于 Fruit implements Comparable<Fruit>
的情况。在这种情况下,Orange
将不是 <T extends Comparable<T>>
的有效候选者,因为 Orange
没有实现 Comparable<Orange>
。因此,您不能将 List<Orange>
作为 List<T>
传递,除非 <T extends Comparable<? super T>>
,这确保可以通过 Fruit
超类将一个 Orange
与另一个进行比较.