set集合:具体体现在不可重复的性质,该集合的特点在于:不会存储重复的元素,存储无序(存入和取出的顺序不一定相同)元素
hashset:是set的经典实现类,底层利用散列表的key值不能重复而实现,hashset具有下面的特性
public static void main(String[] args) { HashSet hs=new HashSet<>(); hs.add("c"); hs.add("a"); hs.add("d"); hs.add(null); hs.stream().forEach(e->{ System.out.println(e); }); } //输出数据 null a c d
整个hashset就像一个容器一般把hashmap得操作操作做了一个封装,实际操作得是hashmap
/** *这个类实现了<tt>Set</tt>接口,由一个哈希表支持(实际上是一个<tt>HashMap</tt>实例)。它不保证*集合的迭代次序;特别是,它不能保证 *随着时间的推移,秩序将保持不变。这个类允许<tt>null</tt>元素。 *<p>该类为基本操作提供恒定时间性能(<tt>添加</tt>、<tt>删除</tt>、<tt>包含</tt>和<tt>大小</tt>),*假设哈希函数将元素正确地分散在 *水桶。迭代这个集合需要的时间与<tt>哈希集</tt>实例的大小(元素数)加上backing<tt>HashMap</tt>实例的“容量”(桶)。因此,不设置初始容量非常重要 *如果迭代性能很重要,则为高(或负载系数太低)。<p><strong>请注意,此实现不同步。</strong>如果多个线程同时访问哈希集,则线程修改集合,它必须在外部同步。这通常是通过在某个自然地封装了集合。 * *如果不存在这样的对象,则应使用{@link Collections#synchronizedSet Collections.synchronizedSet}方法。这最好在创建时完成,以防止意外对集合的非同步访问:<pre>Set s=Collections.synchronizedSet(新HashSet(…))</预处理> * *<p>这个类的<tt>迭代器<tt>方法返回的迭代器是<i>快速失败</i>:如果在迭代器运行后的任何时间修改集合以任何方式创建,除了通过迭代器自己的<tt>remove</tt> *方法,迭代器抛出一个{@link ConcurrentModificationException}。因此,面对并发修改,迭代器很快就会失败而不是冒着武断的、不确定的行为的风险未来不确定的时刻。 *<p>请注意,不能保证迭代器的快速失败行为一般说来,不可能在未来作出任何硬性保证存在未同步的并发修改。失败快速迭代器尽最大努力抛出ConcurrentModificationException。 *因此,编写依赖于此的程序是错误的其正确性例外:<i>迭代器的快速失败行为应仅用于检测错误。</i> * <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @param <E> the type of elements maintained by this set * * @author Josh Bloch * @author Neal Gafter * @see Collection * @see Set * @see TreeSet * @see HashMap * @since 1.2 */
整篇注释得理解
主要是两个成员属性
private transient HashMap<E,Object> map; // 与背景图中的对象关联的虚拟值 private static final Object PRESENT = new Object();
无参构造
给我们提供了一个默认容量 及负载因子得hashmap
public HashSet() { map = new HashMap<>(); }
有参构造
在注释得时候,也建议我们根据实际使用情况,进行设定容量
public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
这里有个疑惑得地方,就是 他里面有个 可以创建LinkedHashMap 得类,可以记录上数据得插入顺序,但是又不是公共得方法,我们不能使用,这个可能是提供给内部使用得把,但又没实现获取顺序得方法,这个也不知道做什么用得
public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; }
这里得add remove 方法,我相信大家都明白,如果需要深究,那可以看一下下面一篇文章
Java 集合深入理解 (十一) :HashMap之实现原理及hash碰撞
整个hashset得实现是非常简单得,基本所有操作都在hashmap中实现,整个数据存储得关键点也在 hashmap中,至于 提供构造方法创建LinkedHashMap 不知道在哪里使用得,还需要理解一下,交流