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 实现。LinkedHashMapHashMap 的子类,它在 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 的插入和查找操作的平均时间复杂度为 O(1),因为它基于哈希表实现。不过,由于需要维护链表来记录插入顺序,其性能略低于 HashSet
  • 空间复杂度LinkedHashSet 的空间复杂度为 O(n),其中 n 是集合中元素的数量。

注意事项

  • 元素的 hashCode()equals() 方法:为了确保 LinkedHashSet 能够正确判断元素是否重复,存储在 LinkedHashSet 中的元素必须正确重写 hashCode()equals() 方法。
  • 线程安全LinkedHashSet 不是线程安全的。如果需要在多线程环境下使用,可以使用 Collections.synchronizedSet() 方法将其转换为线程安全的集合。

应用场景

  • 需要保持插入顺序的去重操作:当你需要对一组数据进行去重,同时又要保留元素的插入顺序时,LinkedHashSet 是一个合适的选择。
  • 缓存机制:在实现缓存时,可能需要按照元素的访问顺序来管理缓存,LinkedHashSet 可以帮助维护这种顺序。
Java集合框架 文章被收录于专栏

Java集合框架是Java提供的一组用于存储和操作数据的类和接口,它位于java.util包中,为开发者提供了强大且灵活的数据存储和处理能力。以下将从整体架构、主要接口、常用实现类、使用场景以及示例代码等方面详细介绍Java集合框架。

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务