类前注释
此类实现了Set
接口,支持哈希表(实际上是一个HashMap)实例。它不保证迭代的顺序;特别是,它不保证顺序的亘久不变。HashSet之处null元素。
假设哈希函数将元素正确地分散在bucket中,该类为基本操作(add,remove,contains和size)提供恒定的时间性能。遍历该集合需要时间正比于HashSet实例的大小(元素的数量)加上其底层HashMap实例的"容量"(桶的数量)的总和。 因此,不要将初始容量设置得太高(或负载因数过低),因为迭代性能很重要,非常重要。
请注意,此实现不是同步的。如果多个线程同时访问HashSet,并且至少有一个线程修改了HashSet,则必须在外部进行同步,这通常是通过对某个对象进行同步来实现的那自然地封装集合。如果该对象不存在,该组应该被"包装"使用Collections.synchronizedSet
方法。 这最好在创建时完成,以防止对set的意外非同步访问:
Set s = Collections.synchronizedSet(new HashSet(...));
此类的iterator方法返回的迭代器是快速失败的:如果集合随时修改创建迭代器之后,以任何方式除非通过迭代器自身的remove方法,迭代器将抛出ConcurrentModificationException
。 因此,在并发的修改时,迭代器很快就会失败,而不是在将来不确定的时间g发生不确定性的行为。
请注意,不能保证迭代器的快速失败行为。通常来说,在存在不同步的并发修改的情况下,不可能做出任何严格的保证。 快速迭代器会尽最大努力抛出ConcurrentModificationException
,因此,编写依赖于此异常的程序的正确性是错误的:迭代器的快速故障行为仅应用于检测错误。
类图
成员变量
//HashSet底层是一个HashMap,key是泛型,value是Object
private transient HashMap<E,Object> map;
//虚拟的值,用于上面的map中的value
private static final Object PRESENT = new Object();
构造方法
//构造一个新的空集; 支持的<tt> HashMap </ tt>实例具有默认的初始容量(16)和负载系数(0.75)。
public HashSet() {
map = new HashMap<>();
}
/**
*构造一个新集合,其中包含指定集合中的元素。HashMap是使用默认加载因子(0.75)和足以容纳指定集合中
*的元素的初始容量创建的。
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
/**
* 构造一个新的空的哈希集。(此构造函数仅供LinkedHashSet使用。)
* 支持的HashMap实例是具有指定的初始容量和指定的负载因子的LinkedHashMap。
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
euqals
HashSet<Integer> set1 = new HashSet<>();
set1.add(1);
set1.add(2);
set1.add(3);
set1.add(4);
TreeSet<Integer> set2 = new TreeSet<>();
set2.add(1);
set2.add(2);
set2.add(3);
set2.add(4);
System.out.println(set1.equals(set2));//true
答案出乎我们的意料,set1和set2的类型都不一样,咋还相等了呢!这就需要查看AbstractSet
的equals
方法了。
/**
* 指定的对象与此Set的相等性。
* 如果给定对象也是Set,这两组具有相同的大小,以及给定的所有成员都包含在这个集合返回true。
* 这样可以确保equals方法可在Set接口的不同实现中正常运行。
*
* 此实现首先检查指定的对象是Set,则返回true。
* 然后,它检查指定的Set的size是相同的; 如果不是,则返回false。
* 如果是这样,则返回containsAll(Collection o)。
*/
public boolean equals(Object o) {
if (o == this)
return true;
//不是Set类型,返回false
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
//集合大小不同,返回false
if (c.size() != size())
return false;
try { //判断另一个集合中的元素是否都在
return containsAll(c);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
版权属于:带翅膀的猫
本文链接:https://www.chengpengper.cn/archives/115/
转载时须注明出处及本声明