Skip to content

Set

Java 中的 SetCollection 体系下的一个重要分支,特点是:不允许元素重复

Set特点

  • 不允许重复元素(通过 equals() 判断)

  • 无索引,不能通过下标访问

  • 一般不保证顺序(部分实现类除外)

  • Set 不存在“覆盖”,当元素相同是无法添加到Set的

实现类

HashSet

HashSet是Set的主要实现类

  • 底层使用HashMap
  • 无序
  • 不重复

通过 hashCode() + equals() 判断是否重复

java
Set<String> set = new HashSet<>();
set.add("A");
set.add("A"); // 不会重复

image-20260328111221147

LinkedHashSet

HashSet 的子类,在HashSet的基础上添加了一组双向链表,用于记录添加元素的先后顺序,我们可以按照添加的顺序进行遍历

  • 有序(插入顺序)
  • 不重复
  • 性能略低于 HashSet
java
Set<String> set = new LinkedHashSet<>();
set.add("B");
set.add("A");

System.out.println(set); // [B, A]

TreeSet

TreeSet使用红黑树存储,TreeSet内部需要进行排序,因此TreeSet只能传入同类型对象。

  • 自动排序(默认升序)

  • 不重复

  • 不允许 null

TreeSet不使用equalshashCode方法比较两个元素是否相等,TreeSet支持Comparable和Comparator进行排序

  • 使用Comparable接口默认排序

compareTo如果返回0,表示两个元素相等,就不会被添加到TreeSet中

java
TreeSet<User> set = new TreeSet<>();

set.add(new User("Tom", 20));
set.add(new User("Jerry", 18));
set.add(new User("Bob", 20)); // ⚠️ 年龄相同

System.out.println(set);
java
public class User implements Comparable<User> {

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 核心:定义排序规则
    @Override
    public int compareTo(User o) {
        // 按年龄升序
        int result = Integer.compare(this.age, o.age);

        return result;
    }

    @Override
    public String toString() {
        return name + "-" + age;
    }
}
java
[Jerry-18, Tom-20]
  • 使用Comparator自定义排序:
java
import java.util.Comparator;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {

        TreeSet<User> set = new TreeSet<>(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                // 按年龄升序
                int result = Integer.compare(o1.getAge(), o2.getAge());

                // 年龄相同再按名字
                if (result == 0) {
                    result = o1.getName().compareTo(o2.getName());
                }

                return result;
            }
        });

        set.add(new User("Tom", 20));
        set.add(new User("Jerry", 18));
        set.add(new User("Bob", 20));

        System.out.println(set);
    }
}
java
[Jerry-18, Bob-20, Tom-20]

Interface Set

接口Set没有添加额外的方法,具体请参考父接口Collection