HashSet的学习
一,HashSet的继承关系
HashSet 是 Set 的一个实现类,而 Set 又继承了Collection 方法,并且没有添加多余的方法。HashSet 继承了AbstractSet 类。
实现了 Cloneable 接口,说明它重写了clone()方法,可以被克隆。实现了 java.io.Serializable 接口,说明它可以被序列化。下面我们看一下源码是如何表示的:
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
二,HashSet的特点
通过源码的解读,我们发现以下四个特点:
1.数据重复性:不能重复 => 底层基于hashmap,hashmap的key是不能重复的,hashset存储的值就是hashmap的key
2.null值处理:只能存在一个null值
3.只能存储单个数据
4.插入数据是无序的
三,基本属性
HashSet的源码中给我们展示了他的三个特有的属性,其余都是继承自HashMap:
map 存储的是键值对,在这里我们只用到了它的 key ,Object 是用来给它的 value 赋值的。所以 HashSet 拥有 HashMap 的所有特性,是用数组加链表的数据结构,并且每个 key 值是唯一的。
static final long serialVersionUID = -5024744406713321676L;
//hashmap类型的map
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
四,构造函数
HashSet拥有五个构造函数:
他们的作用都是对数据结构进行初始化定义,初始大小和容量的初始化等。
五,方法
在HashSet中有:contians,add,remove,iterator,clear,clone等方法,今天我们着重讲一下的他的add方法,首先我们看他在源码中是如何表示的:
我们看到在这个add方法中,传入连个参数,一个是所要插入的元素,一个是HashSet特有的属性PRESENT,然后调用父类HashMap的“put”方法 。这样这个add方法就与我们之前学习HashMap的方法是一致的。有兴趣的可以回看我们之前的HashMap的文章。
六,重点问题
我们之前提到了HashSet是一个单个数据,并且是不重复的,但是他又是继承与HashMap,是一个键值对形式,那么他到底是如何将数据转化为单个元素的呢?
那么就要回到源码当中来,我们发现这样了两个方法:
就是这两个方法,将我们add进来的键值对形式的元素转化为单个元素的形式。在writeObject中,调用了一些方法,然后foreach循环遍历他的键值对的key,然后打印出来。
所以在这里我们只用到了HashMap的 key ,Object 是用来给它的 value 赋值的。这就解释了为什么HashSet为什么是单个元素,并且是无重复的数据了。
七,方法的使用
下面我们将对HashSet的一些常用方法进行使用:
import java.util.HashSet;
/**
* 描述:HashSet
*/
public class HashSetGY2 {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add(2);
hashSet.add(2);
hashSet.add(6);
hashSet.add(9);
hashSet.remove(45);
System.out.println(hashSet);
System.out.println(hashSet.remove(45));
System.out.println(hashSet.size());
}
}
打印结果:
C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=41932:D:\ideaIU-2018.1.5.win\bin -
[2, 6, 9]
false
3
Process finished with exit code 0
如果我们随机打印出三个数据,可以重复,然后我们要求要将这三十个数据中出现重复的数据进行删除,如何呢进行呢?
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
/**
* 描述:删除30个数据中的重复数据
*/
public class Test1 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList();
Random random = new Random();
for (int i = 0; i < 30; ++i) {
arrayList.add(random.nextInt(30) + 1);
}
System.out.println(arrayList);
HashSet<Integer> hashSet = new HashSet();
for (int j = 0; j < 30;++j){
hashSet.add(arrayList.get(j));
}
System.out.println(hashSet);
}
}
打印结果:
C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=41956:D:\ideaIU-2018.1.5.win\bin -
[11, 3, 24, 22, 21, 30, 16, 15, 24, 18, 30, 16, 25, 1, 14, 22, 24, 24, 25, 11, 16, 28, 10, 18, 8, 7, 24, 10, 13, 2]
[1, 2, 3, 7, 8, 10, 11, 13, 14, 15, 16, 18, 21, 22, 25, 24, 28, 30]
Process finished with exit code 0
在这里我们采用ArrayList来存储30个可以重复的数据,根据ArrayList的特性,然后将这30个数据add到HashSet中去,在打印,他就会自己将重复的数据删除了。当然也可以采用HashMap,然后遍历打印他的key值就行。