Java集合之LinkedHashSet

LinkedHashSet详解

1. 简介

     我们知道 HashSet 是无序的,而在HashMap中,为了解决HashMap无序的问题,引入了 LinkedHashMap,所以同样的。为了解决该问题,引入了 LinkedHashSet

2. 继承体系

在这里插入图片描述

3. 深入源码

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    
    public LinkedHashSet() {
        super(16, .75f, true);
    }

    
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

    
    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}
	// LinkedHashSet 都是调用该构造方法创建实例
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

     可以看到,在LinkedHashSet中的方法和属性都很少,可以说其全部都是调用父类的方法。

在这里插入图片描述

4. 总结

     (1)LinkedHashSet的底层使用LinkedHashMap存储元素

     (2)LinkedHashSet是按照插入顺序存储元素的。

### LinkedHashSet 的使用 `LinkedHashSet` 是 Java 集合框架中的一种特殊集合实现,它继承自 `HashSet`,并实现了 `Set` 接口。与 `HashSet` 不同的是,`LinkedHashSet` 通过维护一个双向链表来记录元素的插入顺序,从而保证迭代顺序插入顺序一致[^1]。这种特性使得 `LinkedHashSet` 在需要有序且唯一元素集合的场景中非常有用。 使用 `LinkedHashSet` 时,可以通过以下方式创建和操作集合: ```java import java.util.LinkedHashSet; public class LinkedHashSetExample { public static void main(String[] args) { // 创建一个 LinkedHashSet LinkedHashSet<String> set = new LinkedHashSet<>(); // 添加元素 set.add("Apple"); set.add("Banana"); set.add("Orange"); // 遍历集合 for (String fruit : set) { System.out.println(fruit); } } } ``` 在上述代码中,元素按照插入顺序输出,即 "Apple"、"Banana"、"Orange"。此外,`LinkedHashSet` 不允许重复元素,重复的元素将被忽略。 ### LinkedHashSet 的原理 `LinkedHashSet` 内部实际上是通过 `LinkedHashMap` 来实现的。当向 `LinkedHashSet` 中添加元素时,实际上是将该元素作为 `LinkedHashMap` 的键,而值则是一个固定的虚拟对象(通常是一个 `Object` 实例)[^1]。这种设计使得 `LinkedHashSet` 能够利用 `LinkedHashMap` 的特性来维护元素的插入顺序。 `LinkedHashSet` 的双向链表结构确保了插入顺序的保持。每个元素在被插入时都会被链接到链表的末尾,而重复的元素则不会被重新插入。由于底层是哈希表实现,因此 `LinkedHashSet` 的插入、删除和查找操作的时间复杂度均为 O(1),在保持顺序的同时提供了高效的性能[^1]。 ### LinkedHashSet 的常见问题 1. **为什么 `LinkedHashSet` 能保持插入顺序?** `LinkedHashSet` 能够保持插入顺序的原因在于其内部使用的 `LinkedHashMap`。`LinkedHashMap` 通过维护一个双向链表来记录元素的插入顺序,从而保证了 `LinkedHashSet` 的有序性[^1]。 2. **`LinkedHashSet` 和 `HashSet` 的区别是什么?** `LinkedHashSet` 与 `HashSet` 的主要区别在于顺序性。`HashSet` 不保证元素的顺序,而 `LinkedHashSet` 保证迭代顺序插入顺序一致。这种区别源于 `LinkedHashSet` 使用 `LinkedHashMap` 实现,而 `HashSet` 使用普通的 `HashMap` 实现[^1]。 3. **`LinkedHashSet` 是否允许重复元素?** 不允许。与所有 `Set` 接口的实现类一样,`LinkedHashSet` 不允许包含重复元素。重复的元素会被忽略,不会被再次添加到集合中[^1]。 4. **`LinkedHashSet` 和 `ArrayList` 的区别是什么?** `LinkedHashSet` 和 `ArrayList` 的主要区别在于唯一性和顺序性。`LinkedHashSet` 保证元素的唯一性和插入顺序,而 `ArrayList` 允许重复元素且不保证顺序。此外,`LinkedHashSet` 提供了更快的查找和删除操作,时间复杂度为 O(1),而 `ArrayList` 的查找和删除操作时间复杂度为 O(n)[^1]。 5. **如何在 `LinkedHashSet` 中自定义对象?** 在 `LinkedHashSet` 中使用自定义对象时,必须确保该对象的类正确重写了 `equals()` 和 `hashCode()` 方法,以确保 `LinkedHashSet` 能够正确识别重复对象并维护集合的唯一性[^1]。 ### 示例代码 以下是一个使用 `LinkedHashSet` 存储自定义对象的示例: ```java import java.util.LinkedHashSet; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; if (age != person.age) return false; return name.equals(person.name); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; return result; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class Main { public static void main(String[] args) { LinkedHashSet<Person> people = new LinkedHashSet<>(); people.add(new Person("Alice", 30)); people.add(new Person("Bob", 25)); people.add(new Person("Alice", 30)); // 重复对象,将被忽略 for (Person person : people) { System.out.println(person); } } } ``` 在上述代码中,`Person` 类重写了 `equals()` 和 `hashCode()` 方法,以确保 `LinkedHashSet` 能够正确识别重复对象并维护集合的唯一性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值