Java 集合框架(Set)实战指南:解决你的唯一性问题

 

🔥「炎码工坊」技术弹药已装填!
点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】

 

实际场景:电商系统中用户提交的商品编号必须唯一,如何高效去重?

问题驱动:为何需要 Set?

当用户批量上传商品编号时,重复数据会导致系统异常。传统循环比对方案时间复杂度为 O(n²),性能极差。此时 Java 的 Set 接口正是为高效处理元素唯一性而设计。

// JDK 17 代码示例:使用 HashSet 去重
import java.util.*;

public class ProductIdValidator {
    public static void main(String[] args) {
        // 模拟用户提交的重复商品编号
        List<String> submittedIds = List.of("P1001", "P1002", "P1001", "P1003");
        
        Set<String> uniqueIdSet = new HashSet<>(submittedIds); // 自动去重
        
        System.out.println("去重结果:" + uniqueIdSet);
        // 输出:去重结果:[P1001, P1002, P1003]
    }
}

Set 核心实现对比:三大金刚谁最强?

1. HashSet:速度之王

  • 底层结构:基于 HashMap(数组+链表/红黑树)
  • 特点
    ✅ 插入/查询时间复杂度 O(1)
    ❌ 元素无序
    💡 适合快速去重场景
Set<Integer> hashSet = new HashSet<>();
hashSet.add(3); 
hashSet.add(1); 
hashSet.add(2);
System.out.println(hashSet); // 输出可能为 [1, 2, 3] 或乱序

2. LinkedHashSet:有序卫士

  • 底层结构:链表维护插入顺序
  • 特点
    ✅ 保持元素插入顺序
    ✅ 查询效率接近 HashSet
    💡 适合需要保留历史的缓存场景
Set<Integer> linkedSet = new LinkedHashSet<>();
linkedSet.add(3);
linkedSet.add(1);
linkedSet.add(2);
System.out.println(linkedSet); // 永远输出 [3, 1, 2]

3. TreeSet:排序大师

  • 底层结构:红黑树(自平衡二叉树)
  • 特点
    ✅ 元素自动排序(自然顺序或自定义 Comparator)
    ✅ 提供 first(), last() 等导航方法
    ❌ 插入/删除时间复杂度 O(log n)
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // 永远输出 [1, 2, 3]

性能对比表(10万数据量测试)

实现类插入耗时(ms)查询耗时(ms)内存占用(MB)
HashSet1526.7
LinkedHashSet1837.2
TreeSet35108.1

决策流程图:如何选择 Set 实现?

 

 

高级技巧:自定义对象去重

注意:在 Set 中使用自定义类时,必须重写 equals() 和 hashCode() 方法!

class Product {
    private String id;
    
    public Product(String id) { this.id = id; }

    // 重写 equals 和 hashCode
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return Objects.equals(id, product.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

public static void main(String[] args) {
    Set<Product> products = new HashSet<>();
    products.add(new Product("P1001"));
    products.add(new Product("P1001")); // 重复元素被拒绝
    System.out.println(products.size()); // 输出 1
}

专有名词说明表

术语英文全称解释
SetCollection Set不允许重复元素的集合接口
HashSetHash Set基于哈希表实现的 Set,无序但高效
LinkedHashSetLinked Hash Set维护插入顺序的哈希 Set
TreeSetTree Set基于红黑树实现的有序 Set
红黑树Red-Black Tree自平衡二叉查找树,保证基本操作高效
时间复杂度Time Complexity算法执行时间随数据规模的变化规律
equals/hashCodeObject Equality Methods对象相等性和哈希码的契约方法

建议:在百万级数据去重时,优先选择 HashSet;需要按访问顺序排序时(如LRU缓存),考虑 LinkedHashSet;需要范围查询或自动排序时选择 TreeSet。根据业务场景选择合适工具,才是架构设计的精髓。

 

🚧 您已阅读完全文99%!缺少1%的关键操作:
加入「炎码燃料仓」🚀 获得:
√ 开源工具红黑榜
√ 项目落地避坑指南
√ 每周BUG修复进度+1%彩蛋
(温馨提示:本工坊不打灰工,只烧脑洞🔥) 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值