JavaSE Set集合

  • 明确Set集合接口的特点。

  • java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

  • 特点(重点) : 元素无序 , 去重   底层 : 是 哈希表(哈希值和数组) , 链表 , 红黑树 (根据数据的哈希值来存入集合中(存入前会先调用hashCode()方法来计算数据的哈希值) , 当两个数据哈希值相等时这时会调用eques()方法来判断两个数据是否相等,如果不相等则用链表的的形式存入集合中 ,  当同一个哈希值地址存入了8个以上的链表数据时,这时链表会变成红黑树)  JDK1.8之后才出现的红黑树

  • Set集合有多个子类,这里我们介绍其中的两个(方法就不一 一介绍了继承的Collection,父类的方法可以直接用):

    • java.util.HashSet集合类

    • java.util.LinkedHashSet集合类

小结

Set集合不能通过下标操作数据,所有的方法都是继承Collection集合接口,没有自己的特有方法。Set集合保存数据的特点为: 不能保存重复元素,不保证元素的存取顺序。而因为Set集合并没有下标,所以遍历的方式只能通过迭代器和高级for循环完成。

HashSet集合介绍

  java.util.HashSetSet接口的一个实现类,保存数据的特点为:

  • 存储的元素是不可重复的

  • 保存的元素都是无序的( 即存取顺序不一致 )。

对象的哈希值

 1 package com.itheima.set_01;
 2 /*
 3     02_对象的哈希值
 4     哈希值就是一个十进制的值,是一个对象的特征码(不同对象的哈希值可能重复)
 5 
 6     哈希值如何获取??Object中有一个方法hashCode方法就可以获取
 7 
 8     哈希值能不能自定义?可以,在自定义类中重写该方法即可
 9 
10     哈希值可以自定义,但是如何自定义??我们不会,但是我们可以仿照String类
11     注意:String的哈希值跟它的内容有关。所以自定义对象的哈希值也应该和内容是有关
12 
13 
14     总结:对象的哈希值是跟该对象的内容有关的,不同的对象或者内容不同的对象,可能导致它们的哈希值是一样的
15  */
16 public class HashCodeDemo02 {
17     public static void main(String[] args) {
18         Student student = new Student("张三", 18);
19         int hashCode = student.hashCode();
20         System.out.println(hashCode);//哈希值
21         String str = student.toString();
22         /*
23         底层代码:将真正的内存地址值使用哈希算法求出了哈希值,又被转换成了十六进制
24         public String toString() {
25         return getClass().getName() + "@" + Integer.toHexString(hashCode());
26         }
27 
28         hashcode方法:使用native关键字,是java中jni技术,调用底层C,C++代码在内存开辟空间
29         public native int hashCode();
30 
31 
32          */
33         System.out.println(str);//地址
34     }
35 }

哈希表以及HashSet中去重复的原理

  hashSet去重先判断哈希值,如果不同直接就保存,如果相同,还要调用equals方法再判断内容,如果内容不同也保存

 1 package com.itheima.set_01;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class HashTableDemo03 {
 7     public static void main(String[] args) {
 8         //创建一个存放字符串的Set集合
 9         Set<String> sets = new HashSet<>();
10 
11         String str1 = "abc";
12         String str2 = new String("abc");
13         String str3 = "通话";
14         String str4 = "重地";
15 
16         System.out.println(str1== str2);
17         System.out.println(str1.hashCode());//96354
18         System.out.println(str2.hashCode());//96354
19         System.out.println(str3.hashCode());//1179395
20         System.out.println(str4.hashCode());//1179395
21 
22         sets.add(str1);
23         sets.add(str2);
24         sets.add(str3);
25         sets.add(str4);
26 
27         System.out.println(sets);
28 
29     }
30 }

HashSet存储自定义对象并去重

 1 package com.itheima.set_01;
 2 
 3 import java.util.HashSet;
 4 
 5 /*
 6     04_HashSet存储自定义对象,去重
 7 
 8     总结-要对自定义对象进行去重,必须在类中重写hashCode和equals,自动生成即可
 9  */
10 public class HashSetDemo04 {
11     public static void main(String[] args) {
12         HashSet<Student> sets = new HashSet<>();
13         Student student1 = new Student("张三", 18);
14         Student student2 = new Student("李四", 18);
15         Student student3 = new Student("王五", 18);
16         Student student4 = new Student("张三", 18);
17 
18         //如果没有重写hashcode方法,那么哈希值根据地址值得到的
19         System.out.println(student1.hashCode());
20         System.out.println(student2.hashCode());
21         System.out.println(student3.hashCode());
22         System.out.println(student4.hashCode());
23 
24         //在实际开发中,相同内容的对象,看作是同一个
25 
26         sets.add(student1);
27         sets.add(student2);
28         sets.add(student3);
29         sets.add(student4);
30 
31         System.out.println(sets);
32 
33     }
34 }

LinkedHashSet的扩展

 1 package com.itheima.set_01;
 2 
 3 import java.util.LinkedHashSet;
 4 
 5 /*
 6     Set-存取无序
 7 
 8     04_LinkedHashSet的扩展
 9     LinkedHashSet底层由哈希表+链表,它能保证去重也能保证存取有序
10  */
11 public class LinkedHashSetDemo5 {
12 
13     public static void main(String[] args) {
14         LinkedHashSet<String> sets = new LinkedHashSet<>();
15         sets.add("张飞");
16         sets.add("刘备");
17         sets.add("关羽");
18         sets.add("张飞");
19         System.out.println(sets);
20     }
21 }

猜你喜欢

转载自www.cnblogs.com/ownmg/p/10707134.html