Java HashSet

Set 存“不重复”的元素;HashSet 是 Set 最常用的实现,底层用 HashMap 存放元素,添加、删除、查找都很快,但不保证元素顺序。

特性与基本用法

Set 的特性:不重复(add 重复元素返回 false)且无序。元素没有下标,只能迭代(增强 for 底层是 Iterator)。常用方法 add / remove / contains / size / isEmpty / clear:

import java.util.HashSet;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        System.out.println(set.add("苹果"));  // 输出:true
        System.out.println(set.add("苹果"));  // 输出:false(重复被拒)
        set.add("香蕉");
        System.out.println(set);              // 输出:[香蕉, 苹果](顺序不定)
        for (String s : set) {                // 增强 for 遍历
            System.out.println(s);
        }
        System.out.println(set.contains("苹果")); // 输出:true
        set.remove("苹果");
        System.out.println(set.size());           // 输出:1
    }
}

去重原理:hashCode 与 equals

HashSet 底层是 HashMap,元素作为“键”存放。判重先比 hashCode 定位、再用 equals 精确比较;两个内容相同的对象若没重写这两个方法,会被当成不同元素,去重就会失效。所以向 HashSet 存自定义对象,必须重写 equals 与 hashCode。借 HashSet 还能给 List 去重:new HashSet<>(list) 去重后再 new ArrayList<>(set) 转回(片段需放进 main 方法中运行)。

import java.util.HashSet;
import java.util.Objects;

class User {
    String name;
    User(String name) { this.name = name; }
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof User)) return false;
        return Objects.equals(name, ((User) o).name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

public class UserDemo {
    public static void main(String[] args) {
        HashSet<User> set = new HashSet<>();
        set.add(new User("张三"));
        set.add(new User("张三"));     // 内容相同,被去重
        System.out.println(set.size()); // 输出:1
    }
}

LinkedHashSet 与 TreeSet

两个变体:LinkedHashSet 去重但保持插入顺序;TreeSet 去重并按自然顺序升序排序。

import java.util.LinkedHashSet;
import java.util.TreeSet;

public class SubSetDemo {
    public static void main(String[] args) {
        LinkedHashSet<Integer> l = new LinkedHashSet<>();
        l.add(3); l.add(1); l.add(2);
        System.out.println(l); // 输出:[3, 1, 2](插入顺序)
        TreeSet<Integer> t = new TreeSet<>();
        t.add(3); t.add(1); t.add(2);
        System.out.println(t); // 输出:[1, 2, 3](升序)
    }
}

小结:HashSet 存不重复元素、查询快但无序,判重依赖 hashCode 与 equals;要保序用 LinkedHashSet、要排序用 TreeSet,都可以借助它给 List 去重。

笔记加载中…