我调查LinkedHashSet
和HashSet
收藏。
我写了一个小程序:
public class LHSTest {
public static void main(String[] args){
output(test(new LinkedHashSet()));
System.out.println("=========");
output(test(new HashSet()));
}
public static HashSet<MyClass> test(HashSet hashSet){
hashSet.add(new MyClass(1));
hashSet.add(new MyClass(2));
hashSet.add(new MyClass(3));
hashSet.add(new MyClass(4));
hashSet.add(new MyClass(5));
return hashSet;
}
public static void output(HashSet hashSet){
for(Iterator iterator = hashSet.iterator();iterator.hasNext();){
System.out.println(iterator.next());
}
}
}
class MyClass{
int a;
MyClass(int a){
this.a =a;
}
public int hashCode(){
return 15-a;
}
public String toString() {
return a+"";
}
}
输出:
1
2
3
4
5
=========
5
4
3
2
1
当我看到这种行为时,我开始研究集合的源代码。
我注意到 LinkedHashSet 和 HashSet 都使用
共同toString()
实现——从AbstractCollection
常见iterator()
于HashSet
是什么解释了我的代码LinkedHashSet
和HashSet
在我的代码中的不同输出?
伊万·巴巴宁回答后更新
对于LinkedHashSet
并HashSet
调用不同的构造函数:
对于 LinkedHashSet
-
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
对于 HashSet
-
public HashSet() {
map = new HashMap<E,Object>();
}
HashMap
和 -的迭代器LinkedHasMap
(来自HashSet
)
public Iterator<E> iterator() {
return map.keySet().iterator();
}
研究keySet()
方法:
HashMap
:
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
LinkedHashMap
不能特别实现keySet
方法和使用HashMap
实现。
map.keySet().iterator() is
:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable{
...
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator();
}
...
}
...
}
map.keySet()
返回相同的类型HashMap
,LinkedHashMap
因此调用相同的newEntryIterator()
方法。
是错误的说法吗?
用于 EJP 更新
我导航到HashSet#iterator
: