HashSet , LinkedHashSet与TreeSet
HashSet
-
此类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代次序不作任何保证; 特别是,它不能保证订单在一段时间内保持不变。 这个类允许null元素。
这个类提供了基本操作(add,remove,contains和size)固定的时间性能,假定哈希函数将分散的桶中正确的元素。 迭代此集合需要与HashSet实例的大小(元素数量)和后台HashMap实例(桶数)的“容量”的总和成比例的时间。 因此,如果迭代性能很重要,不要将初始容量设置得太高(或负载因子太低)是非常重要的。
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
HashSet集合特点
1.底层数据结构是哈希表
2.对集合的迭代顺序不做任何保证,也就是说不保证储存和取出的元素顺序一致
3.没有带索引的方法,所以不能使用普通for循环遍历
4.由于是Set集合,所以是不包含重复元素的集合
package com.ye.mySet.itheima03; import java.util.HashSet; public class HashSetDemo1 { public static void main(String[] args) { HashSet<String> hs = new HashSet<>(); hs.add("双笙"); hs.add("叶子"); hs.add("元汐"); hs.add("双笙"); for (String h : hs) { System.out.println(h); } } }
HashSet实例
需求:
创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
要求:学生对象的成员变量吃相同,我们就认为是同一个对象
思路:
1.定义学生类
2.创建HashSet集合对象
3.创建学生对象
4.把学生添加到集合
5.遍历集合(增强for循环)
6.在学生类中重写两个方法
hashCode()和equals()
自动生成即可
HashSet实例方法
package com.ye.mySet.itheima03; import java.util.HashSet; public class HashSetDemo2 { public static void main(String[] args) { //创建一个HashSet集合对象 HashSet<Student> hs = new HashSet<Student>(); //创建学生对象 Student s1 = new Student("双笙",21); Student s2 = new Student("叶子",20); Student s3 = new Student("小曾",19); Student s4 = new Student("双笙",21); //把学生添加到集合 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //遍历集合(增强for循环) for (Student h : hs) { System.out.println(h.getName()+","+h.getAge()); } } }
学生类
package com.ye.mySet.itheima03; import java.util.Objects; public class Student { private String name; private int age; public Student(){ } 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; } @Override public boolean equals(Object o) { 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); } }
LinkedHashSet
-
哈希表和链表实现了Set接口,具有可预测的迭代次序。 这种实现不同于HashSet,它维持于所有条目的运行双向链表。 该链表定义了迭代排序,它是将元素插入集合(插入顺序 ) 的顺序 。 请注意,如果一个元件被重新插入到组插入顺序不受影响 。 (元件e重新插入一组s如果当s.contains(e)将返回true之前立即调用s.add(e)被调用。)
此实现可以让客户从提供的指定,通常杂乱无章的排序
HashSet
,而不会导致与其相关的成本增加TreeSet
。 它可以用于生成与原始文件具有相同顺序的集合的副本,而不管原始集的实现:void foo(Set s) { Set copy = new LinkedHashSet(s); ... }
LinkedHashSet集合特点
1.哈希表和链表实现Set接口,具有可预测的迭代次序
2.由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
3.由哈希表保证元素唯一,也就是说没有重复的元素
package com.ye.mySet.itheima04; import java.util.LinkedHashSet; public class LinkedHashSetDemo01 { public static void main(String[] args) { //创建集合对象 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>(); //添加元素 linkedHashSet.add("双笙"); linkedHashSet.add("叶子"); linkedHashSet.add("元汐"); linkedHashSet.add("双笙"); for (String s : linkedHashSet) { System.out.println(s); } } }
TreeSet
TreeSet是一个有序的集合,它的作用是提供有序的Set集合。它继承了AbstractSet抽象类,实现了NavigableSet,Cloneable,Serializable接口。
TreeSet是基于TreeMap实现的,TreeSet的元素支持2种排序方式:自然排序或者根据提供的Comparator进行排序。
(1)TreeSet继承于AbstractSet,并且实现了NavigableSet接口。
(2)TreeSet是一个包含有序的且没有重复元素的集合,通过TreeMap实现。TreeSet中含有一个"NavigableMap类型的成员变量"m,而m实际上是"TreeMap的实例"。
TreeSet集合特点
1.元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方法取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
2.没有带索引的方法,所以不能使用普通for循环遍历
3.由于是Set集合,所以不包括重复元素的集合
package com.ye.mySet.itheima05; import java.util.TreeSet; public class TreeSetDemo01 { public static void main(String[] args) { //创建集合对象 应该用int类型的包装类型 TreeSet<Integer> ts = new TreeSet<Integer>(); //添加元素 ts.add(10); ts.add(50); ts.add(33); ts.add(22); ts.add(88); //遍历集合对象 for (Integer t : ts) { System.out.println(t); } } }
TreeSet使用Comparable方法实例
存储学生对象并遍历,创建集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.ye.mySet.itheima05; import java.util.TreeSet; public class TreeSetDemo02 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> st = new TreeSet<>(); //创建学生对象 Student s1 = new Student("shuangsheng",20); Student s2 = new Student("yezi",25); Student s3 = new Student("zengsiyu",18); Student s4 = new Student("xiaojiu",2); Student s5 = new Student("wangyuhan",18); Student s6 = new Student("wangyuhan",18); //添加学生到集合 st.add(s1); st.add(s2); st.add(s3); st.add(s4); st.add(s5); st.add(s6); //遍历集合 for (Student s : st) { System.out.println(s.getName()+"\t"+s.getAge()); } } }
学生类
package com.ye.mySet.itheima05; public 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 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; } @Override public int compareTo(Student s) { // return 1; int num = this.age - s.age; //return num; //年龄相同时,按照姓名的字母顺序排序 int num2 = num == 0?this.name.compareTo(s.name):num; return num2; } }
TreeSet使用Comparator方法实例
存储学生对象并遍历,创建TreeSet集合使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
package com.ye.mySet.itheima06; import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { //创建集合对象 TreeSet<Student> st = new TreeSet<Student>(new Comparator<Student>(){ @Override public int compare(Student s1 , Student s2) { int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); Student s1 = new Student("shuangsheng",20); Student s2 = new Student("yezi",25); Student s3 = new Student("zengsiyu",18); Student s4 = new Student("xiaojiu",2); Student s5 = new Student("wangyuhan",18); Student s6 = new Student("wangyuhan",18); st.add(s1); st.add(s2); st.add(s3); st.add(s4); st.add(s5); st.add(s6); for (Student s : st) { System.out.println(s.getName()+"\t"+s.getAge()); } } }
学生类
package com.ye.mySet.itheima06; public class Student { private String name; private int age; public Student(){ } 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; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现