重学Java基础篇—Java集合框架适用于不同的数据存储场景

胶片质感

Java 集合框架的核心接口 ListSetMap 分别适用于不同的数据存储场景,选择正确的集合类型能显著提升代码性能和可维护性。

以下是它们的核心特点及典型使用场景:


1. List(有序、可重复)

特点
  • 有序性:元素按插入顺序存储,支持索引访问(get(index))。
  • 可重复:允许存储相同的元素。
  • 常见实现类
    • ArrayList:基于动态数组,随机访问快(O(1)),尾部增删快,但中间插入/删除慢(O(n))。
    • LinkedList:基于双向链表,插入/删除快(O(1)),但随机访问慢(O(n))。
    • CopyOnWriteArrayList(线程安全):读操作无锁,写操作复制数组,适合读多写少场景。
使用场景
  • 需要保留顺序且允许重复的集合
    • 示例:商品购物车中的商品列表(同一商品可多次添加)。
    List<Product> cart = new ArrayList<>();
    cart.add(product1);
    cart.add(product2); // 允许重复
    
  • 需要根据索引快速访问元素
    • 示例:分页查询结果。
    List<User> userList = userDao.findByPage(pageNo, pageSize);
    User user = userList.get(3); // 直接访问第4个元素
    
  • 需要频繁在头部/中间插入或删除
    • 示例:实现栈(Stack)或队列(Queue)结构(推荐用 LinkedList)。
    LinkedList<LogEntry> logQueue = new LinkedList<>();
    logQueue.addFirst(newLog); // 头部插入
    

2. Set(无序、唯一)

特点
  • 唯一性:不允许重复元素(通过 equals()hashCode() 判断)。
  • 无序性:不保证元素顺序(LinkedHashSet 维护插入顺序,TreeSet 按排序规则存储)。
  • 常见实现类
    • HashSet:基于哈希表,查询/插入/删除快(O(1)),但无序。
    • LinkedHashSet:在 HashSet 基础上维护链表记录插入顺序。
    • TreeSet:基于红黑树,元素按自然顺序或 Comparator 排序,操作时间复杂度 O(log n)。
使用场景
  • 需要自动去重的集合
    • 示例:统计文章关键词(避免重复记录同一词)。
    Set<String> keywords = new HashSet<>();
    keywords.add("Java");
    keywords.add("Collection");
    keywords.add("Java"); // 自动去重
    
  • 需要快速判断元素是否存在
    • 示例:用户权限白名单校验。
    Set<String> allowedRoles = new HashSet<>(Arrays.asList("admin", "editor"));
    if (allowedRoles.contains(userRole)) {
        // 允许访问
    }
    
  • 需要有序且去重的集合
    • 示例:按时间顺序展示用户最近访问的10个城市(用 LinkedHashSet)。
    Set<String> recentCities = new LinkedHashSet<>();
    recentCities.add("北京");
    recentCities.add("上海");
    recentCities.add("北京"); // 去重,且保留插入顺序
    

3. Map(键值对、键唯一)

特点
  • 键唯一性:每个键最多映射一个值(重复键会覆盖旧值)。
  • 无序性:不保证键值对的顺序(LinkedHashMap 维护插入顺序,TreeMap 按键排序)。
  • 常见实现类
    • HashMap:基于哈希表,查询/插入/删除快(O(1))。
    • LinkedHashMap:维护插入顺序或访问顺序(适合实现 LRU 缓存)。
    • TreeMap:按键的自然顺序或 Comparator 排序。
    • ConcurrentHashMap(线程安全):分段锁设计,适合高并发场景。
使用场景
  • 需要键值映射的存储结构
    • 示例:用户信息缓存(键:用户ID,值:用户对象)。
    Map<Long, User> userCache = new HashMap<>();
    userCache.put(1001L, new User(1001, "Alice"));
    User user = userCache.get(1001L); // 通过ID快速查找
    
  • 需要按键排序
    • 示例:按字母顺序展示国家名称与代码(用 TreeMap)。
    Map<String, String> countryCodes = new TreeMap<>();
    countryCodes.put("US", "United States");
    countryCodes.put("CN", "China"); // 自动按键排序
    
  • 需要维护插入顺序或实现 LRU 缓存
    • 示例:记录用户最近浏览的商品(用 LinkedHashMap 维护访问顺序)。
    Map<Long, Product> recentProducts = new LinkedHashMap<>(16, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<Long, Product> eldest) {
            return size() > 100; // 最多保留100个最近访问的商品
        }
    };
    

4. 快速选择指南

需求推荐集合类型示例场景
保留顺序,允许重复ArrayList/LinkedList订单项列表、分页数据
快速去重,无需顺序HashSet用户ID集合、权限白名单
去重且保留插入顺序LinkedHashSet最近搜索记录、访问历史
键值对,快速查找HashMap缓存、配置项存储
键值对,按键排序TreeMap字典、按时间排序的事件记录
高并发读写ConcurrentHashMap多线程共享的缓存或计数器

总结

  • List:处理有序、可重复的线性数据。
  • Set:管理唯一性数据,支持快速存在性检查。
  • Map:建立键值关联,高效通过键检索值。
    根据具体需求(如顺序性、唯一性、排序规则、线程安全)选择合适的实现类,可显著优化代码性能和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Remember_Ray

何其有幸,得你青睐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值