Java集合学习(六)——深入理解HashSet类

320 阅读3分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

前言

 大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习进步。

以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。

摘要

 本文主要介绍Java集合的HashSet类的基本特点和常用的方法。

1. HashSet类

1.1 什么是HashSet类

HashSet类实现了Set接口,底层由哈希表实现,所以查找性能优越。此类不保证迭代顺序,即加入其中的元素顺序可能和读取出来的元素顺序不同。可以加入null元素,并且此类实现不是同步的。

对于HashSet来说,比较两个对象是否相等是通过equals方法和hashCode的返回值来一同决定的。

如果两个对象通过equals方法的结果为true,而hashCode值不同,那么HashSet会认为这是两个对象,但这会与Set的规则相冲突(Set集合不同存放相同元素)。所以如果我们重写了该对象的equals方法,那么最好也重写它的hashCode方法,保持两者一致。即equals方法返回true时,使得hashCode返回相同的值。

如果两个对象通过equals方法返回true,hashCode值也相同,那么才认为这时一个对象。

如果两个对象通过equals方法返回false,而hashCode值相同,那这种情况是我们所不希望的,因为这样会使的两个对象以链式的方式存在相同的位置,这会影响HashSet的查找性能。

1.2 HashSet类的构造方法

参考API文档,HashSet有四个构造方法,分别是:

HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
HashSet(Collection c) 构造一个包含指定 collection 中的元素的新 set。
HashSet(int initialCapacity) 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
HashSet(int initialCapacity, float loadFactor) 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。

实例展示:

HashSet hashSet = new HashSet<String>();
System.out.println(hashSet);
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
HashSet hashSet1 = new HashSet<String>(list);
System.out.println(hashSet1);
HashSet hashSet2 = new HashSet<String>(32);
HashSet hashSet3 = new HashSet<String>(32, 0.8f);

初始容量是底层HashMap的桶的数量,加载因子是到达容量的多少时,进行rehash操作(重建内部数据结构),重构之后,哈希表大约具有两倍的桶的数量。

1.3.3 HashSet类的普通方法

参考API文档:

booleanadd(E e) 如果此 set 中尚未包含指定元素,则添加指定元素。
voidclear() 从此 set 中移除所有元素。
Objectclone()返回此HashSet 实例的浅表副本:并没有复制这些元素本身。
booleancontains(Object o)如果此 set 包含指定元素,则返回true。
booleanisEmpty()如果此 set 不包含任何元素,则返回true。
Iterator<E>iterator() 返回对此 set 中元素进行迭代的迭代器。
booleanremove(Object o) 如果指定元素存在于此 set 中,则将其移除。
intsize() 返回此 set 中的元素的数量(set 的容量)。

HashSet为add,remove,contains和size等基本操作提供了稳定的性能。

实例展示:

HashSet hashSet = new HashSet<String>();
System.out.println(hashSet);
hashSet.add("1");
hashSet.add("2");
hashSet.add("3");
hashSet.add("4");
hashSet.add("0");
System.out.println(hashSet);
System.out.println(hashSet.size());
hashSet.remove("2");
System.out.println(hashSet.contains("2"));
Iterator iterator = hashSet.iterator();
while(iterator.hasNext()){
    Object next = iterator.next();
    System.out.println(next);
}
​
hashSet.clear();
System.out.println(hashSet.isEmpty());

image-20211128200424576

结果也进一步说明HashSet是不保证迭代顺序的。

小结

以上就是我对HashSet类的一些浅见,希望对读者有所帮助,如有不正之处,欢迎留言评论。