文章中的部分照片来源于哔站
黑马程序员阿伟老师
处,仅用学习,无商用,侵权联系删除!
具体信息请查看 API 帮助文档
1. 概述
LinkedHashSet是Java集合框架中的一种集合实现,它是HashSet和LinkedHashMap的结合体。它通过使用哈希表和双向链表来实现元素的存储和维护插入顺序。
LinkedHashSet的特点:
-
有序性:LinkedHashSet内部使用双向链表来维护元素的插入顺序。因此,通过迭代LinkedHashSet,可以按照元素插入的顺序进行访问。
-
唯一性:与HashSet类似,LinkedHashSet不允许存储重复的元素。它通过哈希表来快速查找并判断元素的唯一性。
-
快速访问:像HashSet一样,LinkedHashSet在添加、删除和查找元素时具有较高的性能。通过哈希表的结构,它能够在常数时间内执行这些操作。
-
允许存储null元素:LinkedHashSet和HashSet一样,允许存储一个null元素。
LinkedHashSet集合底层原理:
-
有序,不重复,无索引
-
底层基于哈希表,使用双链表记录添加顺序
LinkedHashSet的应用场景主要是需要保留元素插入顺序并且对快速查找、删除元素有要求的场景。在需要按照元素插入顺序进行迭代的情况下,LinkedHashSet是一个不错的选择。
需要注意的是,LinkedHashSet相对于HashSet在内存使用上略微更多,因为它需要维护链表来保持元素的顺序。在大量数据存储的情况下,可能会占用更多的内存空间。
2. 方法
LinkedHashSet
集合是hashSet
集合的子类,是Set
集合的孙子类,是Collection
集合的重孙子类,因此hashSet
集合、Set
集合和Collection
集合的方法都可以使用
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
boolean removeIf(Object o) | 根据条件进行移除 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
3. 遍历方式
【注意】LinkedHashSet集合没有索引,因此只能用迭代器遍历、增强 for ,Lambda表达式遍历。
与共有的 集合遍历方式 一样
- 代码示例
利用LinkedHashSet集合去除重复元素。
需求:创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
要求:学生对象的成员变量值相同,我们就认为是同一个对象,并且学生的存入顺序和输出顺序一致
package text.text02;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Objects;
/*
LinkedHashSet集合:
1.有序,不重复,无索引
2.底层基于哈希表,使用双链表记录添加顺序
*/
public class text39 {
public static void main(String[] args) {
//创建集合对象
LinkedHashSet<Student3> linkedHashSet = new LinkedHashSet<>();
//添加学生对象并输出添加结果
System.out.println(linkedHashSet.add(new Student3("张三", 23))); //true
System.out.println(linkedHashSet.add(new Student3("李四", 24))); //true
System.out.println(linkedHashSet.add(new Student3("王五", 25))); //true
System.out.println(linkedHashSet.add(new Student3("马超", 25))); //true
System.out.println(linkedHashSet.add(new Student3("刘备", 27))); //true
System.out.println(linkedHashSet.add(new Student3("关羽", 15))); //true
System.out.println(linkedHashSet.add(new Student3("张飞", 31))); //true
System.out.println(linkedHashSet.add(new Student3("张三", 23))); //false
//遍历集合
Iterator<Student3> it = linkedHashSet.iterator();
while (it.hasNext()) {
Student3 str = it.next();
System.out.print("[" + str.getName() + "," + str.getAge() + "] "); //[张三,23] [李四,24] [王五,25] [马超,25] [刘备,27] [关羽,15] [张飞,31]
}
}
}
//重写了hashCode方法和equals方法的学生类
class Student3 {
private String name;
private int age;
public Student3() {
}
public Student3(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
*
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
*
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
*
* @param 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;
Student3 student3 = (Student3) o;
return age == student3.age && name.equals(student3.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public String toString() {
return "Student3{name = " + name + ", age = " + age + "}";
}
}
- 输出结果
4. 注意事项
-
保留插入顺序:LinkedHashSet会按照元素插入的顺序维护集合中的元素。这意味着当你迭代集合时,元素的顺序将与它们被插入的顺序一致。但是需要注意的是,如果你在集合中添加了重复元素(根据equals方法判断),重复的元素将不会改变或重新排序。
-
不允许重复元素:与HashSet类似,LinkedHashSet也不允许存储重复的元素。如果你尝试向集合中添加重复的元素,重复的元素将会被忽略掉。
-
性能:LinkedHashSet在查找和删除元素方面具有较高的性能。由于它使用了哈希表作为底层的数据结构,这些操作的时间复杂度是常数时间。但是需要注意的是,LinkedHashSet相对于HashSet来说,在内存使用上稍微更多一些,因为它需要维护元素插入顺序的链表结构。
-
可以存储null元素:LinkedHashSet可以存储null元素,但只能存储一个null元素。尝试添加多个null元素时,只会保留一个,其他的将会被忽略掉。