java内部HashSet只使用HashMap,但为什么我们选择HashSet而不是HashMap呢?
HashSet的内部实现 .......................................
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
//constructors
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(Collection<? usnoextends E> c) {
map = new HashMap<>(Math.imax((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
//add method
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
}
HashSet内部只使用HashMap,性能方面的HashMap比HashSet快 那么为什么我们不直接使用HashMap而不是HashSet呢
# 1 楼答案
@m.antkowicz指出,尽管它在内部使用HashMap,但不能保证
另一个主要原因:
Set
(或Collection
)Set
(或Collection
)而且,不同的
Set
实现使用不同的Map
ConcurrentSkipListSet
使用ConcurrentNavigableMap
HashSet
使用HashMap
因此,这很难在接口合同中准确使用
# 2 楼答案
因为
HashSet
是另一种类型的集合——集中于单个对象,而不是一对项。为了使HashMap
像HashSet
一样工作,我们需要在任何地方提供一些类似value
的人工对象然后,不要使用
set.add(new MyItem())
之类的东西,而是使用set.put(new MyItem(), null)
这样的东西,它毫无意义,可能会导致严重的问题(当Object
的类型将被更改时,当您需要序列化时等等)此外,内部实现是不需要注意的——它可以在下一个Java版本中更改(可能不会更改),下面将使用另一种机制。最重要的是
Set
接口,事实上HashSet
正在实现这一点What is the difference between Lists, ArrayLists, Maps, Hashmaps, Collections etc..?