我有三个类:1.class Algorithm
max()
在Collection
中找到最大值:
public class Algorithm {
public static <T extends Comparable<T>> T max(Collection<? extends T> coll) {
T max = coll.iterator().next();
for (T elm : coll) {
if (max.compareTo(elm) < 0)
max = elm;
}
return max;
}
}
2.Class Fruit
:
public class Fruit implements Comparable<Fruit> {
private String name;
private int size;
public Fruit(String name, int size) {
this.name = name;
this.size = size;
}
public int compareTo(Fruit that) {
if (size < that.size)
return -1;
else if (size == that.size)
return 0;
else
return 1;
}
}
3.class Apple
延长Fruit
:
public class Apple extends Fruit {
public Apple(int size) {
super("Apple", size);
}
}
现在的问题是:
public class Main
{
public static void main(String[] args) {
Apple a1 = new Apple(10);
Apple a2 = new Apple(34);
List<Apple> apples = Arrays.<Apple>asList(a1, a2);
System.out.println(Collections.max(apples).size);
}
}
根据这篇文章Java - Syntax Question: What is 我应该这样写:public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)
。但它现在工作正常。为什么?类Apple
未实现Comparable<Apple>
,且没有super
。
[UPDATE]
Java Generics and Collections Book说:
没有
super
通配符,找到List<Apple>
的最大值 即使找到List<Fruit>
的最大值,也是非法的 允许的。
答案 0 :(得分:5)
假设我们将max
方法更改为:
<T extends Comparable<T>> T max(Collection<? extends T> coll)
由于max
未实现List<Apple>
,因此无法获得Apple
的{{1}},它会实现Comparable<Apple>
。但是你和我完全清楚Comparable<Fruit>
知道如何将自己与另一个Apple
进行比较,因为它继承了这个功能。
我们通过将Fruit
的声明更改为此来解决问题:
max
这意味着我们接受任何类<T extends Comparable<? super T>> T max(Collection<? extends T> coll)
,以便:
T
,或...... T implements Comparable<T>
的T implements Comparable<X>
,X
是X
为了找到T
,我们必须确保max
的任何实例都可以安全地接受另一个T
实例作为其T
方法的参数。
在第一个场景中,很明显compare
的任何实例都可以安全地接受另一个T
实例作为其T
方法的参数。
在第二种情况下,compare(T)
的任何实例都可以安全地接受T
的另一个实例作为其T
方法的参数,因为compare(X)
的所有实例也是实例T
。
您的示例说明了第二种情况,X
对应T
而Apple
对应X
。
答案 1 :(得分:1)
您使用Collections.max(apples)
代替Algorithm.max
。
Collections.max
声明略有不同:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
答案 2 :(得分:0)
很抱歉把它带回去,但我认为这很重要。从Collections.max()更改为Algorithm.max()时,您的代码是否已停止正常工作?我已经在jdk8中完成了一个类似的测试,我不明白它为什么工作正常,而根据Java Generics和Collections它不应该。
我有一个Fruit抽象类(实现Comparable):
public abstract class Fruit implements Comparable<Fruit> {
private String name;
private int size;
public Fruit(String name, int size) {
this.name = name;
this.size = size;
}
public int compareTo(Fruit that) {
if (size < that.size)
return -1;
else if (size == that.size)
return 0;
else
return 1;
}
}
然后我有一个Apple扩展Fruit类:
public class Apple extends Fruit {
public Apple(String name, int size) {
super(name, size);
}
}
最后:
public class GenericsTest {
@Test
public void test1() {
final Apple a1 = new Apple("apple1", 50);
final Apple a2 = new Apple("apple2", 70);
final Apple a3 = new Apple("apple3", 34);
final List<Apple> apples = Lists.newArrayList(a1, a2, a3);
System.out.println(GenericsTest.max(apples).getSize());
}
private static <T extends Comparable<T>> T max(Collection<? extends T> coll) {
T max = coll.iterator().next();
for (T elm : coll) {
if (max.compareTo(elm) < 0)
max = elm;
}
return max;
}
}
代码正在运行而没有? max方法签名中的super T和List属于Apple类型。根据你提到的报价,它应该不起作用。我好像在这里感到困惑......