我一直在阅读Effective Java,但我遇到了无界的集合类型<?>
。但是,阅读使我相信您不能将null
以外的任何元素放入Collection<?>
的实例中。
所以,我的问题是:当我们只能插入Collection<?>
元素时,实例化null
的目的是什么,因为它似乎毫无意义。我一直试图找出这个概念,但它似乎没有多大意义。任何帮助将不胜感激。
答案 0 :(得分:24)
Collection<?>
允许您创建接受任何类型的Collection
作为参数的方法。例如,如果您想要一个返回true
的方法,如果Collection
中的任何元素等于某个值,您可以执行以下操作:
public boolean collectionContains(Collection<?> collection, Object toCompareTo) {
for (Object o : collection) {
if (toCompareTo.equals(o)) return true;
}
return false;
}
任何类型的Collection
:
Set<String> strings = loadStrings();
collectionContains(strings, "pizza");
Collection<Integer> ints = Arrays.toList(1, 2, 3, 4, 5);
collectionContains(ints, 1337);
List<Collection<?>> collections = new ArrayList<>();
collectionContains(collections, ILLEGAL_COLLECTION);
答案 1 :(得分:5)
考虑以下Util方法from docs
以下方法向您展示如何使用Iterator过滤任意Collection - 即遍历删除特定元素的集合。
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
这段简单的代码是多态的,这意味着无论实现,它都适用于任何Collection
。
答案 2 :(得分:1)
当您使用通配符声明集合时,请指定该集合是所有类型集合的超类型。
当你有一个方法可以传递所有类型的集合时,这非常有用,例如:
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
请看Oracle's documentation关于外卡的内容,因为它非常详尽。
答案 3 :(得分:1)
Collection
是所有Lists
和Sets
的最低抽象。最好使用你可以使用的最低抽象,因为它可以为你提供更大的灵活性,你的代码更健壮,因为它可以处理所有Lists
或Sets
或其他实现,而不是甚至还得实施。
好吧,Collection与Collection<Object>
相当。它只是表示存储在Collection
中的对象的泛型类型是未知,或者您可以使用Object
本身的任何对象的最低抽象。在这种情况下,您可以将任何对象放入Collection
,甚至可以将其与不同类型混合使用。但是你必须要知道在运行时将它转换为正确的类型,因为你没有提供你的Collection存储的Object类型。因此,Collection无法将Object转换为适合您的类型,您必须自己完成。要识别正确的类型,您应该在运行时使用Object instanceof SomeOtherClass
或Class.isAssignableFrom(Class)
。
同样Collection
没有实现get()
方法,但您可以通过这种方式获取Iterator
并从集合中获取对象。