为什么 Java 集合删除方法不是泛型的?

2022-08-31 07:38:31

为什么Collection.remove(Object o)不是通用的?

似乎可以有Collection<E>boolean remove(E o);

然后,当您不小心尝试从 中删除(例如)而不是每个单独的 String 时,这将是编译时错误,而不是以后的调试问题。Set<String>Collection<String>


答案 1

remove()(in 以及 in ) 不是通用的,因为您应该能够将任何类型的对象传递给 。删除的对象不必与您传入的对象的类型相同;它只要求他们是平等的。从 的规范中,删除的对象,如下所示。请注意,没有任何要求并且是相同的类型。这是因为该方法采用 as 参数,而不仅仅是与对象相同的类型。MapCollectionremove()remove()remove()remove(o)e(o==null ? e==null : o.equals(e))trueoeequals()Object

虽然,许多类已经定义了它的对象只能等于它自己类的对象,这当然不是总是如此。例如,的规范说,如果两个 List 对象都是 List 并且具有相同的内容,即使它们是 的不同实现,则两个 List 对象是相等的。因此,回到这个问题中的示例,可以有一个和我用as参数调用,并且它应该删除键,即具有相同内容的列表。如果是通用的并限制了其参数类型,则不可能做到这一点。equals()List.equals()ListMap<ArrayList, Something>remove()LinkedListremove()


答案 2

Josh Bloch 和 Bill Pugh 在 Java Puzzlers IV: The Phantom Reference Threatace、Attack of the Clone 和 Revenge of The Shift 中提到了这个问题。

Josh Bloch说(6:41),他们试图将Map的get方法,remove方法和其他一些方法进行进化,但“它根本行不通”。

如果只允许集合的泛型类型作为参数类型,则有太多合理的程序无法生成。他给出的例子是 a of s 和 a of s 的交集。ListNumberListLong