Java HashSet内部只使用HashMap,但是为什么我们要使用HashSet而不是HashMap呢?
HashSet的内部实现Java HashSet内部只使用HashMap,但是为什么我们要使用HashSet而不是HashMap呢?,java,dictionary,collections,hashmap,hashset,Java,Dictionary,Collections,Hashmap,Hashset,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(); //construc
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;
}
}
公共类哈希集
扩展抽象集
实现Set、Cloneable、java.io.Serializable
{
私有瞬态HashMap;
私有静态最终对象存在=新对象();
//建设者
公共哈希集(){
map=新的HashMap();
}
公共哈希集(int initialCapacity){
map=新HashMap(初始容量);
}
公共哈希集(int initialCapacity,float loadFactor){
map=新的HashMap(初始容量、负载因子);
}
公共HashSet(Collection,因为HashSet
是另一种类型的集合-集中于单个对象而不是一对项。要使HashMap
像HashSet
一样工作,我们需要在任何地方提供一些类似于
HashMap<MyItem, Object> set;
HashMap集;
然后使用类似于set.put(new MyItem(),null)
的方法来代替例如set.add(new MyItem())
什么没有意义并且可能导致严重问题(当对象的类型发生变化时,当您需要序列化时等等)
此外,内部实现是不需要注意的-它可以在下一个Java版本中更改(可能不会更改),下面将使用另一种机制。最重要的是Set
接口,事实上HashSet
正在实现它
因为HashSet
是另一种类型的集合-集中于单个对象而不是一对项。要使HashMap
像HashSet
一样工作,我们需要在任何地方提供一些类似于
HashMap<MyItem, Object> set;
HashMap集;
然后使用类似于set.put(new MyItem(),null)
的方法来代替例如set.add(new MyItem())
什么没有意义并且可能导致严重问题(当对象的类型发生变化时,当您需要序列化时等等)
此外,内部实现是不需要注意的-它可以在下一个Java版本中更改(可能不会更改),下面将使用另一种机制。最重要的是Set
接口,事实上HashSet
正在实现它
正如@m.antkowicz所指出的,尽管它在内部使用HashMap,但无法保证
另一个主要原因是:
通常在大型项目中,接口的定义独立于实现
如果业务接口需要Set(甚至是Collection),它会将其定义为Set
(或Collection
)
接口不关心底层实现(它们假定将保持预期的行为)
接口的任何业务具体实现都应该准确地声明方法签名(以覆盖)
因此,他们还将使用Set
(或Collection
)
另外,Set
的不同实现使用不同的Map
ConcurrentSkipListSet
使用ConcurrentNavigableMap
HashSet
使用HashMap
因此,很难在接口契约中准确地使用它。正如@m.antkowicz所指出的,尽管它在内部使用HashMap,但无法保证
另一个主要原因是:
通常在大型项目中,接口的定义独立于实现
如果业务接口需要Set(甚至是Collection),它会将其定义为Set
(或Collection
)
接口不关心底层实现(它们假定将保持预期的行为)
接口的任何业务具体实现都应该准确地声明方法签名(以覆盖)
因此,他们还将使用Set
(或Collection
)
另外,Set
的不同实现使用不同的Map
ConcurrentSkipListSet
使用ConcurrentNavigableMap
HashSet
使用HashMap
因此,在接口契约中很难准确地使用它。在某些情况下,您可能希望使用集合而不是hashmap。您确切的问题是什么?您所说的“性能方面的hashmap比HashSet快”是什么意思?在某些情况下,您可能希望使用集合而不是hashmap。您确切的问题是什么?您所说的“性能方面的hashmap比HashSet快”是什么意思?