个人主页→VON
收录专栏→java从入门到起飞
目录
编辑
一、前言
二、简要概述
三、Set集合
四、HashSet集合
五、LinkedHashSet集合
一、前言
HashSet集合和LinkHashSet集合都是Set集合的分支集合,语法大致相同。这些众多的集合虽然许多地方都十分相近,但是底层的原理还是大相径庭的。希望大家能够仔细分辨。
二、简要概述
在Java中,Set
是一个不允许包含重复元素的集合。Set
接口是Collection
接口的子接口,它继承了Collection
的所有方法,并且增加了对唯一性元素存储的支持。Set
的主要实现类有以下几种:
HashSet:
- 基于哈希表实现。
- 不保证元素的存储顺序。
- 插入、删除和查找操作的时间复杂度为 O(1),即常数时间。
- 元素可以通过
hashCode()
和equals()
方法来确定其位置。
LinkedHashSet:
- 继承自
HashSet
,但在内部使用了一个双向链表来链接所有的条目。 - 保持元素的插入顺序。
- 通常比
HashSet
慢一点,因为维护了链表的连接关系。
三、Set集合
Set集合的特点
- 无序、不重复、无索引
- Set集合的方法上基本与Collection的API一致
Set集合的实现类特点
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:可排序、不重复、无索引
java">package ArrayDemo.SetDemo;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class A01_SetDemo01 {public static void main(String[] args) {// 1.创建一个Set集合的对象Set<String> s = new HashSet<>();// 2.添加元素// 如果元素是第一次添加,则可以添加成功,返回true// 如果元素是第二次添加,则添加失败,返回falseSystem.out.println(s.add("张"));// trueSystem.out.println(s.add("李"));// trueSystem.out.println(s.add("李"));// falseSystem.out.println(s.add("李"));// falseSystem.out.println(s);// [张, 李]// 3.遍历集合// 增强for遍历for (String s1 : s) {System.out.println(s1);}// 迭代器遍历Iterator<String> str = s.iterator();while(str.hasNext()){System.out.println(str.next());}// Lambda表达式s.forEach(str1 -> System.out.println(str1));}
}
四、HashSet集合
Student类在这里就不过多赘述了,直接快速生成就行了。快捷键想必大家也十分熟悉了。
哈希值:
对象的整体表现形式
- 如果没有重写hashCode方法,计算出的哈希值是不同的
- 如果已经重写hashCode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
- 但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样
java">package ArrayDemo.SetDemo;public class A02_HashSetDemo01 {public static void main(String[] args) {// 1.创建对象Student s1 = new Student("zhang",18);Student s2 = new Student("zhang",18);// 2.如果没有重写hashCode方法,计算出的哈希值是不同的System.out.println(s1.hashCode());// 495053715System.out.println(s2.hashCode());// 1922154895// 3.如果已经重写hashCode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的System.out.println(s1.hashCode());// -703165081System.out.println(s1.hashCode());// -703165081// 4.但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样System.out.println("abc".hashCode());// 96354System.out.println("acD".hashCode());// 96354}
}
需求:
创建一个存储学生对象的集合,存储多个学生对象
使用程序实现在控制台遍历该集合
要求:学生对象的成员变量值相同,我们就认为是同一个对象
java">package ArrayDemo.SetDemo;import java.util.HashSet;public class A03_HashSetDemo02 {public static void main(String[] args) {// 1.创建四个学生对象Student s1 = new Student("zhang",18);Student s2 = new Student("wang",18);Student s3 = new Student("li",18);Student s4 = new Student("zhang",18);// 2.创建集合存储学生对象HashSet<Student> hs1 = new HashSet<>();HashSet<Student> hs2 = new HashSet<>();// 3.添加元素(没有重写HashSet)System.out.println(hs1.add(s1));// trueSystem.out.println(hs1.add(s2));// trueSystem.out.println(hs1.add(s3));// trueSystem.out.println(hs1.add(s4));// trueSystem.out.println(hs1);// [Student{name = zhang, age = 18}, Student{name = li, age = 18}, Student{name = zhang, age = 18}, Student{name = wang, age = 18}]// 4.添加元素(重写HashSet)System.out.println(hs2.add(s1));// trueSystem.out.println(hs2.add(s2));// trueSystem.out.println(hs2.add(s3));// trueSystem.out.println(hs2.add(s4));// falseSystem.out.println(hs2);// [Student{name = zhang, age = 18}, Student{name = li, age = 18}, Student{name = wang, age = 18}]}
}
五、LinkedHashSet集合
java">package ArrayDemo.SetDemo;import java.util.LinkedHashSet;public class A04_LinkedHashSetDemo04 {public static void main(String[] args) {// LinkedHashSet集合的特点和原理// 有序、不重复、无索引// 底层基于哈希表、使用双链表记录添加顺序// 1.创建四个学生对象Student s1 = new Student("zhang",18);Student s2 = new Student("wang",18);Student s3 = new Student("li",18);Student s4 = new Student("zhang",18);// 2.创建集合对象LinkedHashSet<Student> lhs = new LinkedHashSet<>();// 3.添加学生对象System.out.println(lhs.add(s1));// trueSystem.out.println(lhs.add(s3));// trueSystem.out.println(lhs.add(s2));// trueSystem.out.println(lhs.add(s4));// falseSystem.out.println(lhs);// [Student{name = zhang, age = 18}, Student{name = li, age = 18}, Student{name = wang, age = 18}]}
}