Skip to content

Set的使用与代码题常见场景


一、Set是什么?

Set是Java集合框架中的接口(java.util.Set),表示不包含重复元素的集合。核心特点:

  1. 元素唯一性(自动去重)
  2. 无序性(除LinkedHashSetTreeSet外)
  3. 允许一个null元素 常用实现类:
  • HashSet:基于哈希表,最快查询
  • LinkedHashSet:保持插入顺序
  • TreeSet:基于红黑树,自动排序

二、解决什么问题

  1. 去重需求:自动过滤重复元素
  2. 快速存在性检查:高效判断元素是否存在(O(1)时间复杂度)
  3. 集合运算:交集、并集、差集等操作
  4. 无序唯一集合:不需要索引的场景

三、核心方法

java
// 常用方法
boolean add(E e)      // 添加元素(重复返回false)
boolean contains(Object o) // 检查存在性
boolean remove(Object o)   // 删除元素
int size()            // 元素数量
boolean isEmpty()     // 判空
void clear()          // 清空集合

// JDK8+新增
boolean removeIf(Predicate<? super E> filter) // 条件删除
Spliterator<E> spliterator() // 并行遍历

四、应用场景(代码题高频)

  1. 去重操作

    java
    List<Integer> list = Arrays.asList(1, 2, 2, 3, 4, 4);
    Set<Integer> uniqueSet = new HashSet<>(list); // 自动去重
    System.out.println(uniqueSet); // [1, 2, 3, 4]
  2. 存在性检查

    java
    Set<String> dictionary = new HashSet<>(Arrays.asList("apple", "banana"));
    System.out.println(dictionary.contains("apple")); // true
  3. 统计不同元素数量

    java
    String text = "hello world";
    long charCount = text.chars().distinct().count(); // JDK8流式API
  4. 集合运算(交集/并集/差集)

    java
    Set<Integer> setA = new HashSet<>(Arrays.asList(1, 2, 3));
    Set<Integer> setB = new HashSet<>(Arrays.asList(3, 4, 5));
    
    // 交集
    setA.retainAll(setB); // setA变为[3]
    
    // 并集
    setA.addAll(setB);    // setA变为[1,2,3,4,5]
    
    // 差集
    setA.removeAll(setB); // 移除setB中的元素
  5. 字母异位词检查

    java
    boolean isAnagram(String s1, String s2) {
        return Arrays.equals(
            s1.chars().sorted().toArray(),
            s2.chars().sorted().toArray()
        );
    }

五、不同Set实现对比

特性HashSetLinkedHashSetTreeSet
顺序无序插入顺序自然排序
性能O(1)O(1)O(log n)
排序支持
线程安全

六、重要注意事项

  1. 重写hashCode()和equals()

    • 自定义对象放入Set需正确重写这两个方法
    java
    class Student {
        String id;
        // 必须重写
        @Override
        public int hashCode() { return id.hashCode(); }
        @Override
        public boolean equals(Object o) { /*...*/ }
    }
  2. TreeSet排序规则

    • 元素需实现Comparable接口,或创建时传入Comparator
    java
    Set<Integer> sortedSet = new TreeSet<>((a, b) -> b - a); // 降序
  3. 线程安全问题

    • 非线程安全,多线程环境用:
    java
    Set<Object> safeSet = Collections.synchronizedSet(new HashSet<>());
  4. JDK9+工厂方法

    java
    Set<String> fastSet = Set.of("A", "B", "C"); // 不可变集合

七、总结

在代码题中优先考虑Set:

  1. 需要去重时 → 首选HashSet
  2. 需要保持插入顺序LinkedHashSet
  3. 需要自动排序TreeSet
  4. 高频操作:存在性检查(contains())、集合运算(addAll/removeAll)

最佳实践

  • 大数据量去重用HashSet
  • 需要顺序访问用LinkedHashSet
  • 范围查询(如找最大/最小值)用TreeSet
  • JDK8+优先使用Stream API配合Set操作