Vik*_*ahl 4 java generics collections
我正在用java编写一个skiplist类作为练习.我写了一个名为SkipListInternal<E>
包含实际跳过列表的类.我还创建了一个包装器类SkipListSet<E>
,它实现了SortedSet<E>
接口并包含一个实例SkipListInternal<E>
.
除其他外,SkipListInternal<E>
包含一个E find(E e)
返回元素的方法,e
如果它存在,则返回null,否则返回null.
在编写boolean contains(Object o)
(继承自Collection<E>
via SortedSet<E>
)方法时,我注意到它的参数是一个Object而不是E.我打算做这样的事情,但由于类型擦除而不可能:
public class SkipListSet<E> implements SortedSet<E>{
private SkipListInternal<E> skiplist;
...
public boolean contains(Object o){
if (!(o instanceof E)) return false;
return skiplist.find((E) o) != null;
}
...
}
Run Code Online (Sandbox Code Playgroud)
既然不能这样做,我该怎么做呢?
严格来说,这样的实施是错误的.
这样做的原因是,即使对象不是类型E
,它仍然可以true
在equals()
通话时返回.
假设你有一个这样的课:
public class FakeString {
private final String value;
public FakeString(String value) {
if (value == null) {
throw new IllegalArgumentException();
}
this.value = value;
}
public int hashCode() {
return value.hashCode();
}
public boolean equals(Object o) {
return value.equals(o);
}
}
Run Code Online (Sandbox Code Playgroud)
然后这段代码将打印出来true
:
List<String> strings = Arrays.asList("foo", "bar", "baz");
System.out.println(strings.contains(new FakeString("bar")));
Run Code Online (Sandbox Code Playgroud)
并且只是为了澄清:这种行为是有意的,并且是为什么contains()
需要Object
代替E
.remove()
顺便说一句,情况也是如此.