第十七章 Java的容器(set)

本文详细介绍了Java中三种常用的集合类型:HashSet、LinkedHashSet和TreeSet。重点讲解了它们的底层实现原理,包括哈希表、链表及排序机制,并探讨了自定义对象存储时需要注意的重写方法。

1.HashSet集合底层依赖的是哈希表,存储自定义对象要重写HashCode()和equals()方法

 1 package cn.itcast_01;
 2 import java.util.HashSet;
 3 import java.util.Set;
 4 /*
 5  * HashSet集合存储自定义对象并遍历,对象的属性值相同定义为一个相同的对象
 6  * 注意:你使用的是HashSet集合,这个集合的底层是哈希表结构。
 7  *         而哈希表结构底层依赖:hashCode()和equals()方法。
 8  *         如果你认为对象的成员变量值相同即为同一个对象的话,你就应该重写这两个方法。
 9  */
10 public class HashSetDemo {
11     public static void main(String[] args) {
12         //注意:Student没有重写hashCode()和equals()方法。
13         //Dog类重写了hashCode()和equals()方法。
14         Set<Student> set1 = new HashSet<Student>();
15         Set<Dog> set2 = new HashSet<Dog>();
16         //创建对象并添加元素
17         Student s1 = new Student("张三", 11);
18         Student s2 = new Student("张三", 11);
19         Student s3 = new Student("李四", 11);
20         Dog d1 = new Dog("Tomcat", 22);
21         Dog d2 = new Dog("Tomcat", 22);
22         Dog d3 = new Dog("Apache", 22);
23         set1.add(s1);
24         set1.add(s2);
25         set1.add(s3);
26         set2.add(d1);
27         set2.add(d2);
28         set2.add(d3);
29         //集合遍历
30         for (Student s : set1) {
31             System.out.println(s.getName()+"--"+s.getAge());
32         //李四--11   张三--11   张三--11
33         }
34         for (Dog dog : set2) {
35             System.out.println(dog.getName()+"--"+dog.getAge());
36         //Tomcat--22    Apache--22
37         //重写了hashCode()和equals()
38         }
39     }
40 }

2.LinkedHashSet底层依赖的是哈希表和链表(保证唯一性和有序存储)

 1 package cn.itcast_01;
 2 
 3 import java.util.LinkedHashSet;
 4 import java.util.Set;
 5 
 6 /*
 7  * LinkedHashSet集合底层数据结构时哈希表和链表
 8  * 哈希表保证元素的唯一性
 9  * 链表保证存储元素的有序(存储和取出是一致)
10  */
11 public class LinkedHashSetDemo {
12     public static void main(String[] args) {
13         Set<String> set = new LinkedHashSet<String>();
14         Set<Dog> set1 = new LinkedHashSet<Dog>();
15         /*set.add("hello");
16         set.add("hello");
17         set.add("world");
18         set.add("java");
19         set.add("myJava");*/
20         Dog d1 = new Dog("dog", 11);
21         Dog d2 = new Dog("dog", 11);
22         Dog d3 = new Dog("dog", 11);
23         /*for (String string : set) {
24             System.out.println(string);
25             //hello,world,java,myJava
26         }*/
27         set1.add(d1);
28         set1.add(d2);
29         set1.add(d3);
30         //自定义的类对象一定要重写HashCode和equals方法否则无法保证元素的唯一性
31         for (Dog dog : set1) {
32             System.out.println(dog);
33         }
34     }
35 }

3.TreeSet集合:能够对元素进行排序(排序和唯一)基本数据的包装类和String都实现了Comparable接口

 1 package cn.itcast_01;
 2 import java.util.Iterator;
 3 import java.util.Set;
 4 import java.util.TreeSet;
 5 
 6 /*
 7  * TreeSet集合的特点:排序和唯一
 8  * TreeSet:能够对元素按照某种规则进行排序。
 9  * 自然排序和比较器排序
10  */
11 public class TreeSetDemo {
12     public static void main(String[] args) {
13         Set<Integer> set = new TreeSet<Integer>();
14         //TreeSet() 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
15         //TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
16         set.add(55);
17         set.add(88);
18         set.add(11);
19         set.add(11);
20         set.add(22);
21         set.add(100);
22         /*Iterator<Integer> it = set.iterator();
23         while(it.hasNext()){
24             System.out.println(it.next());
25         }*/
26         for (Integer i : set) {
27             System.out.println(i);
28         }
29         //11,22,,55,88,100
30     }
31 }

想要类对象实现自定义排序,该类要自己实现Comparable接口(外比较器)

 1 package cn.itcast_01;
 2 import java.util.Iterator;
 3 import java.util.Set;
 4 import java.util.TreeSet;
 5 
 6 /*
 7  * TreeSet集合的特点:排序和唯一
 8  * TreeSet:能够对元素按照某种规则进行排序。
 9  * 自然排序和比较器排序
10  */
11 public class TreeSetDemo2 {
12     public static void main(String[] args) {
13         //Cat类不需要重写HashCode()和equals()方法了,重复的自然就搞走了
14         //实现Comparable接口来进行排序compareTo()方法>0往后排
15         Set<Cat> cats = new TreeSet<>();
16         Cat c1 = new Cat("Tomcat1", 33);
17         Cat c2 = new Cat("Tomcat2", 22);
18         Cat c3 = new Cat("Tomcat3", 11);
19         Cat c4 = new Cat("Tomcat4", 44);
20         cats.add(c1);
21         cats.add(c2);
22         cats.add(c3);
23         cats.add(c4);
24         for (Cat cat : cats) {
25             System.out.println(cat);
26         }
27     }
28 }

 

 1 @Override
 2     public int compareTo(Cat o) {
 3         //主要排序按年龄
 4         int num =this.age - o.age;
 5         /*//次要排序按姓名
 6         if(num==0){
 7             int num1 = this.name.compareTo(o.name);
 8             return num1;
 9         }*/
10         int num1 = num ==0?this.name.compareTo(o.name):num;
11         return num1;
12     }

Comparator接口(外比较器)在外面自定义了一个排序类,还类实现了Comparator接口

public class Student{}

public class MyComparator implements Comparator<Student>{}

TreeSet集合还可以使用内部类的方式让对象类实现Comparator接口

 1 package cn.itcast_01;
 2 import java.util.Comparator;
 3 import java.util.Set;
 4 import java.util.TreeSet;
 5 /*
 6  * TreeSet集合的特点:排序和唯一
 7  * TreeSet:能够对元素按照某种规则进行排序。
 8  * 自然排序和比较器排序
 9  */
10 public class TreeSetDemo2 {
11     public static void main(String[] args) {
12         // Cat类不需要重写HashCode()和equals()方法了,重复的自然就搞走了
13         Set<Cat> cats = new TreeSet<>(new Comparator<Cat>() {
14             @Override
15             public int compare(Cat c1, Cat c2) {
16                 // 姓名长度
17                 int num = c1.getName().length() - c2.getName().length();
18                 // 姓名内容
19                 int num2 = num == 0 ? c1.getName().compareTo(c2.getName()) : num;
20                 // 年龄
21                 int num3 = num2 == 0 ? c1.getAge() - c2.getAge() : num2;
22                 return num3;
23             }
24         });
25         Cat c1 = new Cat("Tomcat1", 33);
26         Cat c2 = new Cat("Tomcat2", 11);
27         Cat c3 = new Cat("Tomcat3", 11);
28         Cat c4 = new Cat("Tomcat4", 44);
29         cats.add(c1);
30         cats.add(c2);
31         cats.add(c3);
32         cats.add(c4);
33         for (Cat cat : cats) {
34             System.out.println(cat);
35         }
36     }
37 }

 

转载于:https://www.cnblogs.com/syg13129953117/p/7979176.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值