可能重复:
What are the reasons why Map.get(Object key) is not (fully) generic
Why does Java's TreeSet<E> remove(Object) not take an E
为什么HashSet不限制E的参数类型:
public boolean contains(Object o)
public boolean remove(Object o)
就像添加()
一样public boolean add(E e)
我的意思是如果编译器强制只添加E类型的对象,那么该集合不能包含/删除任何其他类型
答案 0 :(得分:4)
不同之处在于添加必须是类型安全的,以保持集合的完整性,而项目检查/删除可以提供“类型宽容”,而不会有损害集合类型安全性的风险。换句话说,如果添加错误类型的元素,该集将变为无效;另一方面,如果您检查是否存在错误类型的元素,您只需返回false
。同样适用于remove
:如果传递一个不兼容类型的元素,它将不会出现在集合 + 中,因此删除将是一个无操作。
答案 1 :(得分:2)
然后该集不能包含/删除任何其他类型
当然可以。阅读type erasure或将HashSet<E>
投射到非通用HashSet
,并添加一个非E
类型的对象。
查看此代码:
Integer testInt = new Integer(3);
// First, create a generic set of strings
HashSet<String> set = new HashSet<String>();
set.add("abc");
// Then make it non-generic and add an integer to it
((HashSet) set).add(testInt);
// Now your set-of-strings contains an integer!
System.out.println(set); // prints: [abc, 3]
// Remove the integer
set.remove(testInt);
System.out.println(set); // prints: [abc]
这种奇怪的原因是泛型类型的信息在运行时被删除,而你的集合变成了一组简单的对象。
答案 2 :(得分:2)
contains
和remove
的参数不能仅限于E
,因为您应该能够为它们提供相同的对象,这非常有用。更准确地说,HashSet.remove
的API说:
...更正式地,删除一个元素e(o == null?e == null: o.equals(e)),如果这个集合包含这样的元素。
Object.equals
将Object
作为参数,这对于启用不同类型之间的相等也非常有用。
因此,要启用contains
和remove
的更一般功能(在等价类而不是仅对象标识上),他们必须将Object
作为参数。
示例:
HashSet<ArrayList<String>> set = new HashSet<ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
list.add("foo");
LinkedList<String> equalList = new LinkedList<String>();
equalList.add("foo");
set.add(list);
System.out.println(list.equals(equalList)); // prints: true
System.out.println(set.contains(equalList)); // prints: true
System.out.println(set); // prints: [[foo]]
set.remove(equalList);
System.out.println(set); // prints: [[]]
答案 3 :(得分:0)
您没有使用这两种方法向集合中添加任何内容,因此不需要约束type参数。如果类型不匹配,则方法只能返回false。