Set接口
Set接口简要介绍
Set接口和List接口都一样继承自Collection接口,所以两者方法基本相似。但是Set接口中没有与索引相关的方法,这就确定了Set接口无序的特点。
HashSet的特点
1.放入的数据无序,且不重复
HashSet hs = new HashSet();
hs.add(19);
hs.add(23);
hs.add(99);
hs.add("abc");
hs.add(19);
hs.add("abc");
System.out.println(hs.size());
System.out.println(hs);
这里看似放入了6个数据,但实际上底层只存入了没有重复的四个数据;对其进行打印,可以发现四个数据并不按存放的先后顺序进行打印
4
[19, 99, abc, 23]
2.重复放入的数据的有效值
(1).查看 add()方法,可知方法返回值为boolean类型
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
(2).对调用add()方法的结果进行打印,判断生效的数值是哪一个
HashSet hs = new HashSet();
System.out.println(hs.add(19));//有效数据
hs.add(23);
hs.add(99);
System.out.println(hs.add("abc"));//有效数据
System.out.println(hs.add(19));
System.out.println(hs.add("abc"));
//结果
true
true
false
false
由此可见,有效的数据是第一个
(3).添加数据类型定为自定义的引用数据类型
创建一个简易的Student类
public class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
添加Student引用数据类型
HashSet<Student> hs = new HashSet<>();//将HashSet的泛型定为Student引用数据类型
hs.add(new Student("danqiang",18));
hs.add(new Student("limo",20));
hs.add(new Student("hanlijun",19));
hs.add(new Student("danqiang",18));
hs.add(new Student("hanlijun",19));
再次对集合的长度和元素进行打印
System.out.println(hs.size());
System.out.println(hs);
/*结果*/
5
[Test_Set.Student@74a14482, Test_Set.Student@677327b6, Test_Set.Student@4554617c, Test_Set.Student@1b6d3586, Test_Set.Student@1540e19d]
按照前面所说的“数据唯一不重复”的特性,调用size()的结果应该为3,并且只打印三个对象;但打印结果却不满足这个特点。这与HashSet的原理有关,见下。
HashSet底层简易原理图
1.存入的数据首先计算hashCode
2.再将得到的哈希值经过一个表达式计算之后得到数据即将放入底层数组的位子
3.将数据存到相应的位置,当该位置已经有值时,且不与这些值重复,则通过链表连接在该位置数据后面。
LinkedHashSet特点
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(12);
linkedHashSet.add(34);
linkedHashSet.add(35);
linkedHashSet.add(12);
linkedHashSet.add(34);
System.out.println(linkedHashSet.size());
System.out.println(linkedHashSet);
/*结果*/
3
[12, 34, 35]
由上图可见,LinkedHashSet依然保证唯一性,但是打印时数据具有有序性。
LinkedHashSet就是在HashSet的基础上多了一个总链表,这个总链表将放入的元素串在一起,方便有序的遍历。