集合(二):Set : HashSet;LinkedHashSet;TreeSet

it2022-05-05  180

文章目录

集合(二)Set一、HashSet1、概述及特点2、HashSet元素唯一性解析及代码优化代码优化 二、LinkedHashSet三、TreeSet1、概述及特点二叉树存储数据保证元素唯一性且排序原理图解 2、自然排序演示 3、比较器排序演示 4、例题 四、Collections工具类

集合(二)

Set

概述及特点:元素唯一,即一个不包含重复元素的 collection。更确切地讲, set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。

一、HashSet

1、概述及特点

概述及特点:HashSet 底层数据结构是哈希表,线程不安全,效率高,元素无序(存取顺序 不一致),且唯一(元素不可重复),可以是 null。 哈希表:JDK1.7之前是数组+链表,JDK1.8之后为数组+链表+二叉树

2、HashSet元素唯一性解析及代码优化

代码优化

import java.util.HashSet; import java.util.Objects; public class Blog1 { public static void main(String[] args) { //HashSet 之所以能够保证元素的唯一性,是靠元素重写 equals()和hashCode()方法来保证的,如果元素不重写该方法,则不能保证元素的唯一性 //合理重写hashCode()方法,可以减少调用equals()的次数,也称之为减少碰撞 //原因:只有当两个对象hashCode()的返回值相同时,才会去调用equals()方法,比较成员变量的内容 HashSet<Student> hashSet = new HashSet<>(); hashSet.add(new Student("张三",23)); hashSet.add(new Student("李四",27)); hashSet.add(new Student("王五",26)); hashSet.add(new Student("张三",23)); hashSet.add(new Student("李四",27)); hashSet.add(new Student("王五",26)); hashSet.add(new Student("赵六",25)); hashSet.add(new Student("张三",24)); hashSet.add(new Student("曾七",23)); System.out.println(hashSet); } } class Student{ String name; int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } static int count=1;//统计变量 @Override public boolean equals(Object o) { System.out.println("equals()方法执行了"+(count++)+"次"); if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, age); } } 运行结果: equals()方法执行了1equals()方法执行了2equals()方法执行了3[Student{name='张三', age=23}, Student{name='李四', age=27}, Student{name='王五', age=26}, Student{name='赵六', age=25}, Student{name='张三', age=24}, Student{name='曾七', age=23}] Process finished with exit code 0

二、LinkedHashSet

概述及特点:LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一, 链表保证了有序,哈希表保证了唯一,线程不安全,效率高

三、TreeSet

1、概述及特点

概述及特点:TreeSet 底层数据结构是二叉树,元素唯一,且可以对元素进行排序, 排序:自然排序,比较器排序

二叉树存储数据保证元素唯一性且排序原理图解

2、自然排序

自然排序:如果TreeSet()采用的是空参构造,那么采用的就是自然排序,自然排序要求元素必须 实现一个Comparable接口,并实现这个接口中的一个compareTo比较方法,根据此方法的返回值的 正(右边) 、负(左边) 0(两元素相同,不再向集合添加) 来决定元素排列的位置。

演示

import java.util.TreeSet; public class Blog2 { public static void main(String[] args) { TreeSet<Student> treeSet = new TreeSet<>(); treeSet.add(new Student("张三",23)); treeSet.add(new Student("李四",27)); treeSet.add(new Student("王五",26)); treeSet.add(new Student("张三",23)); treeSet.add(new Student("李四",27)); treeSet.add(new Student("王五",26)); treeSet.add(new Student("赵六",25)); treeSet.add(new Student("张三",24)); treeSet.add(new Student("曾七",23)); //按照年龄从小到大排序 System.out.println(treeSet); } } class Student implements Comparable<Student> { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } //重写比较方法 @Override public int compareTo(Student o) { //先比较年龄大小,如果年龄大小一样,再去比较名字,如果不比较名字,年龄相同的人就存不到集合中去了 int num=this.age-o.age; int num1=num==0?this.name.compareTo(o.name):num; return num1; } } 运行结果: [Student{name='张三', age=23}, Student{name='曾七', age=23}, Student{name='张三', age=24}, Student{name='赵六', age=25}, Student{name='王五', age=26}, Student{name='李四', age=27}] Process finished with exit code 0

3、比较器排序

比较器排序:采用有参构造,在创建TreeSet对象时,需要传入一个Comparetor 比较器 //TreeSet(Comparator < ? super E > comparator) Comparator<T> 比较器: int compare (T o1, T o2);//比较用来排序的两个参数。

演示

import java.util.Comparator; import java.util.TreeSet; public class Blog3 { public static void main(String[] args) { //传入比较器方式:1、可以自己创建一个Comparator<T>接口的子类,并实现 compare方法,传入该接口的子类对象 // 2、使用匿名内部类,传入比较器,并实现compare方法 TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int num=o1.getAge()-o2.getAge(); int num1=num==0?o1.getName().compareTo(o2.getName()):num; return num1; } }); treeSet.add(new Student("张三",23)); treeSet.add(new Student("李四",27)); treeSet.add(new Student("王五",26)); treeSet.add(new Student("张三",23)); treeSet.add(new Student("李四",27)); treeSet.add(new Student("王五",26)); treeSet.add(new Student("赵六",25)); treeSet.add(new Student("张三",24)); treeSet.add(new Student("曾七",23)); //按照年龄从小到大排序 System.out.println(treeSet); } } class Student{ private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } 运行结果: [Student{name='张三', age=23}, Student{name='曾七', age=23}, Student{name='张三', age=24}, Student{name='赵六', age=25}, Student{name='王五', age=26}, Student{name='李四', age=27}] Process finished with exit code 0

4、例题

//需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复,且要对其进行排序 /*-----示例-----*/ import java.util.Random; import java.util.TreeSet; public class Blog4 { public static void main(String[] args) { int number=10; Random random = new Random(); TreeSet<Integer> treeSet = new TreeSet<>(); //Integer类已经实现Comparable接口,默认从小到大排序 for (int i = 0; i < number; i++) { boolean flag=treeSet.add(random.nextInt(20)+1);//生成随机数尝试添加到集合,并获取是否添加成功的结果 if(!flag){ i--;//如果未添加成功,让i-1,多生成一个随机数添加尝试添加到集合 } } System.out.println(treeSet); } } 运行结果: [1, 5, 6, 7, 10, 11, 12, 14, 15, 17] Process finished with exit code 0

四、Collections工具类

A:Collections类概述: 针对集合操作的工具类 B:Collections常用成员方法 public static <T> void sort(List<T> list): 排序,默认按照自然顺序 public static <T> int binarySearch(List<?> list,T key): 二分查找 public static <T> T max(Collection<?> coll): 获取最大值 public static void reverse(List<?> list): 反转集合元素 public static void shuffle(List<?> list): 随机打乱元素

最新回复(0)