LinkedHashSet<E>
LinkedHashSet<E>
是 Java 集合框架中的一个类,它继承自 HashSet<E>
,同时实现了 Set<E>
接口。LinkedHashSet
结合了哈希表和链表的特性,既能够保证元素的唯一性,又能维护元素的插入顺序。以下将从多个方面详细介绍 LinkedHashSet<E>
类。
类定义与继承关系
LinkedHashSet<E>
类的定义如下:
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable
- 继承自
HashSet<E>
,复用了HashSet
的部分实现逻辑。 - 实现了
Set<E>
接口,表明它存储的元素是唯一的。 - 实现了
Cloneable
接口,意味着该类的实例可以被克隆。 - 实现了
java.io.Serializable
接口,表明该类的对象可以被序列化。
底层实现原理
LinkedHashSet
底层基于 LinkedHashMap
实现。LinkedHashMap
是 HashMap
的子类,它在 HashMap
的基础上维护了一个双向链表,用于记录元素的插入顺序。在 LinkedHashSet
中,元素作为 LinkedHashMap
的键,而 LinkedHashMap
的值统一使用一个静态的 PRESENT
对象。
主要特性
- 元素唯一性:和
HashSet
一样,LinkedHashSet
不允许存储重复元素。判断元素是否重复依赖于元素的hashCode()
和equals()
方法。 - 插入顺序维护:
LinkedHashSet
会按照元素的插入顺序来维护元素,即遍历LinkedHashSet
时,元素的顺序与插入顺序一致。 - 允许
null
元素:LinkedHashSet
允许存储一个null
元素。
常用构造方法
LinkedHashSet()
:创建一个空的LinkedHashSet
,初始容量为 16,负载因子为 0.75。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); } }
LinkedHashSet(Collection<? extends E> c)
:创建一个包含指定集合中所有元素的LinkedHashSet
。
import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; public class LinkedHashSetExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); LinkedHashSet<String> set = new LinkedHashSet<>(list); } }
LinkedHashSet(int initialCapacity)
:创建一个具有指定初始容量的空LinkedHashSet
,负载因子为 0.75。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(20); } }
LinkedHashSet(int initialCapacity, float loadFactor)
:创建一个具有指定初始容量和负载因子的空LinkedHashSet
。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(20, 0.8f); } }
常用方法
LinkedHashSet
继承了 HashSet
的方法,常用方法如下:
boolean add(E e)
:如果指定元素不存在于集合中,则将其添加到集合中,添加成功返回true
,否则返回false
。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); boolean result = set.add("apple"); System.out.println(result); // 输出 true result = set.add("apple"); System.out.println(result); // 输出 false } }
boolean remove(Object o)
:如果集合中存在指定元素,则将其移除,移除成功返回true
,否则返回false
。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); boolean result = set.remove("apple"); System.out.println(result); // 输出 true } }
boolean contains(Object o)
:判断集合中是否包含指定元素,包含返回true
,否则返回false
。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); boolean result = set.contains("apple"); System.out.println(result); // 输出 true } }
int size()
:返回集合中元素的数量。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); set.add("banana"); int size = set.size(); System.out.println(size); // 输出 2 } }
void clear()
:移除集合中的所有元素。
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); set.clear(); System.out.println(set.size()); // 输出 0 } }
遍历方式
和 HashSet
类似,LinkedHashSet
也有多种遍历方式:
- 迭代器(Iterator):
import java.util.Iterator; import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); set.add("banana"); Iterator<String> iterator = set.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); } } }
- 增强 for 循环:
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); set.add("banana"); for (String element : set) { System.out.println(element); } } }
- Java 8 的
forEach
方法结合 Lambda 表达式:
import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>(); set.add("apple"); set.add("banana"); set.forEach(element -> System.out.println(element)); } }
性能分析
- 插入和查找操作:
LinkedHashSet
的插入和查找操作的平均时间复杂度为,因为它基于哈希表实现。不过,由于需要维护链表来记录插入顺序,其性能略低于
HashSet
。 - 空间复杂度:
LinkedHashSet
的空间复杂度为,其中
是集合中元素的数量。
注意事项
- 元素的
hashCode()
和equals()
方法:为了确保LinkedHashSet
能够正确判断元素是否重复,存储在LinkedHashSet
中的元素必须正确重写hashCode()
和equals()
方法。 - 线程安全:
LinkedHashSet
不是线程安全的。如果需要在多线程环境下使用,可以使用Collections.synchronizedSet()
方法将其转换为线程安全的集合。
应用场景
- 需要保持插入顺序的去重操作:当你需要对一组数据进行去重,同时又要保留元素的插入顺序时,
LinkedHashSet
是一个合适的选择。 - 缓存机制:在实现缓存时,可能需要按照元素的访问顺序来管理缓存,
LinkedHashSet
可以帮助维护这种顺序。
Java集合框架 文章被收录于专栏
Java集合框架是Java提供的一组用于存储和操作数据的类和接口,它位于java.util包中,为开发者提供了强大且灵活的数据存储和处理能力。以下将从整体架构、主要接口、常用实现类、使用场景以及示例代码等方面详细介绍Java集合框架。