[英]Can I somehow exclude or filter out a value from Collections.Min/Collections.Max in java?
[英]Signature of Collections.min/max method
在Java中,Collections類包含以下方法:
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)
它的簽名因其對泛型的高級使用而聞名,因此在Java的Nutshell書籍和官方的Sun Generics Tutorial中都提到了它。
但是,我無法找到以下問題的令人信服的答案:
為什么Collection<? extends T>
的形式參數Collection<? extends T>
Collection<? extends T>
,而不是Collection<T>
? 還有什么好處?
類型推斷是一個棘手的話題,我承認我不太了解。 但是,請檢查此示例:
public class ScratchPad {
private static class A implements Comparable<A> {
public int compareTo(A o) { return 0; }
}
private static class B extends A {}
private static class C extends B {}
public static void main(String[] args)
{
Collection<C> coll = null;
B b = Scratchpad.<B>min(coll);
}
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c) {
return null;
}
//public static <T extends Object & Comparable<? super T>> T min(Collection<T> c) {
// return null;
//}
}
考慮min()的第一個簽名允許調用編譯而第二個簽名不允許。 這不是一個非常實際的例子,因為我必須問為什么我會明確地將方法鍵入<B>
,但也許有一個隱式推理,其中B
將是推斷類型。
一個好處是?
是它禁止添加項目Collection
我認為它實際上並沒有為這個方法提供更多的東西,但是當T是類的一部分而不僅僅是靜態方法時,它是一個很好的習慣。
他們在這里包括它,所以它可以成為新的約定,每個通用應該擴展?
一類T應遵循PECS: 什么是PECS(Producer擴展消費者超級)?
但是靜態方法不需要(至少參數,返回值應該總是)
這是為了支持Java 1.4(以及之前)中方法的遺留簽名。
在Java 5之前,這些方法的簽名是
public static Object min ( Collection c );
使用多個邊界時,擦除規則使第一個綁定方法的原始類型,因此沒有Object &
簽名就可以了
public static Comparable min ( Collection c );
和遺留代碼會破裂。
這取自O'Reilly的Java Generics and Collections一書,第3.6章
根據我對馬克答案的評論,如果你有類似的話
class Play {
class A implements Comparable<A> {
@Override
public int compareTo(A o) {
return 0;
}
}
class B extends A {
}
class C extends A {
}
public static <T extends Object & Comparable<? super T>> T min(
Collection<? extends T> c) {
Iterator<? extends T> i = c.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) < 0)
candidate = next;
}
return candidate;
}
public static List<? extends A> getMixedList() {
Play p = new Play();
ArrayList<A> c = new ArrayList<A>();
c.add(p.new C());
c.add(p.new B());
return c;
}
public static void main(String[] args) {
ArrayList<A> c = new ArrayList<A>();
Collection<? extends A> coll = getMixedList();
A a = Play.min(coll);
}
}
min更清楚的是返回A類型的對象(實際簽名是<A> A Play.min(Collection<? extends A> c)
)。 如果你離開min(Collection<T>)
沒有extends部分,那么Play.min(coll)
將具有以下簽名<? extends A> ? extends A Play.min(Collection<? extends A> c)
<? extends A> ? extends A Play.min(Collection<? extends A> c)
<? extends A> ? extends A Play.min(Collection<? extends A> c)
,這個不太清楚。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.