一、Set 核心定义

Set 是 Java 单列集合 Collection 的核心子接口(非类),定义「无序、不可重复、无索引」的单列集合规范,仅存储独立元素,自动去重,无法通过索引操作元素,需通过实现类落地功能。


二、Set 核心特性

1. 不可重复性:集合中不允许存储值相等的元素(自动去重,去重规则由实现类决定);

2. 无序性:元素存储顺序与遍历顺序不一定一致(LinkedHashSet 除外,保留插入顺序);

3. 无索引:不支持整数索引访问/操作元素,无法用普通 for 循环遍历;

4. 继承 Collection 特性:支持泛型、动态扩容、通用增删查遍历方法,默认实现类均非线程安全;

5. 可空性:HashSet/LinkedHashSet 允许存储 1 个 null 元素,TreeSet 不允许存储 null 元素。


三、Set 核心实现类(3个必掌握)

1. HashSet(最常用,无序去重)

• 去重规则:依赖元素的 hashCode() 和 equals() 方法(核心重点):

1. 先调用元素的 hashCode() 计算存储位置;

2. 若位置为空,直接存入元素;

3. 若位置非空,调用 equals() 对比元素:相等则去重(不存入),不相等则处理哈希冲突后存入;

• 性能:查询、增删效率高(时间复杂度 O(1)),无序;

• 线程安全:非线程安全;

• 适用场景:无需保证顺序,仅需快速去重的场景(如存储不重复的用户 ID、手机号)。

2. LinkedHashSet(有序去重)

• 底层实现:「哈希表 + 双向链表」(基于 HashSet 扩展,链表记录元素插入顺序);

• 核心优势:兼具 HashSet 的快速去重/高效操作,同时保留元素「插入顺序」(遍历顺序 = 插入顺序);

• 去重规则:与 HashSet 一致(依赖 hashCode() 和 equals());

• 性能:效率略低于 HashSet(多了链表维护顺序的开销),有序;

• 线程安全:非线程安全;

• 适用场景:需要去重且需保留插入顺序的场景(如按添加顺序存储唯一的操作记录)。


四、Set 核心方法(继承 + 特有)

继承 Collection 的通用方法(核心常用)

• 增:boolean add(E e)(添加元素,重复则返回 false,不存入)、boolean addAll(Collection<? extends E> c)(添加另一个集合元素,自动去重);

• 删:boolean remove(Object o)(删除指定元素,成功返回 true)、void clear()(清空集合);

• 查:int size()(返回元素个数)、boolean isEmpty()(判断是否为空)、boolean contains(Object o)(判断是否含指定元素,依赖 equals/hashCode 或排序规则);

• 转换:Object[] toArray()、<T> T[] toArray(T[] a)(转为指定类型数组)。


五、Set 遍历方式(2种,无普通 for 循环)

1. 迭代器遍历(最安全,支持遍历中删除)
Set<String> set = new HashSet<>();
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
    String elem = iterator.next();
    // 遍历中删除元素(必须用 iterator.remove(),避免并发修改异常)
    if (elem.equals("无效值")) {
        iterator.remove();
    }
}
2. 增强 for 循环(简洁,不支持遍历中删除)
for (String elem : set) {
    System.out.println(elem);
}



六、Set 去重/排序关键注意事项

1. HashSet/LinkedHashSet 去重(必重写 2 个方法)

• 存储自定义对象(如 User、Student)时,必须同时重写对象的 hashCode() 和 equals() 方法,否则无法正确去重(默认用 Object 类的地址比较,相同对象不同地址会被视为不同元素);

• 重写原则:equals() 返回 true 时,hashCode() 必须返回相同值;hashCode() 不同时,equals() 必须返回 false(保证逻辑一致)。



七、Set 实现类选择依据

1. 优先选 HashSet:无需顺序,仅需快速去重(性能最优,日常开发最常用);

2. 选 LinkedHashSet:需要去重 + 保留插入顺序(略牺牲性能换有序);

一句话总结:Set 是「无序/有序、不可重复、无索引」的单列集合,核心能力是去重(+ 排序),关键掌握实现类的底层结构和去重/排序规则 


八、代码

1.

package testset;

import java.util.HashSet;
import java.util.Set;

public class TestSet1 {
    public static void main(String[] args) {
        //利用set集合添加多个字符串
        Set<String> strs=new HashSet<>();
        String s1=new String ("hello");
        String s2=new String ("world");
        String s3=new String ("java");
        String s4=new String ("java");

        System.out.println(s3==s4);
        System.out.println(s3.equals(s4));

        strs.add(s1);
        strs.add(s2);
        strs.add(s3);
        strs.add(s4);
        //
        for(String s:strs){
            System.out.println(s);
        }

2.

package testset;

import java.util.HashSet;
import java.util.Set;

public class TestSet2 {
    public static void main(String[] args) {
        Set<Student> set=new HashSet<>();
        Student s1=new Student("小李",29,99.8);
        Student s2=new Student("小红",18,95.8);
        Student s3=new Student("小黄",38,65.0);
        Student s4=new Student("小黄",38,65.0);

        System.out.println(s3==s4);//false
        System.out.println(s3.equals(s4));

        set.add(s1);
        set.add(s2);
        set.add(s3);
        for(Student s:set){
            System.out.println(s);
        }
    }
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐