当前位置: 首页 > news >正文

Java 数据结构你会用几种?—— 从“只会 ArrayList”到“精准选型”(附 Spring Boot 实战场景)

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!(发点评论可以给博主加热度哦)


一、真实痛点:为什么你总在“乱用”数据结构?

  • ArrayList存唯一 ID,结果重复了?
  • HashMap遍历顺序乱了,前端对不上?
  • LinkedList随机访问,性能慢成狗?
  • 高并发下HashMap直接 CPU 100%?

🚨问题根源:你只知道List list = new ArrayList(),却不知道每种数据结构的底层原理和适用场景

本文将带你盘点Java 中最常用的 8 种数据结构,结合Spring Boot 真实业务场景 + 正反案例对比,让你从此“精准选型,不再踩坑”!


二、Java 核心数据结构速查表

数据结构底层实现是否有序是否唯一线程安全典型场景
ArrayList动态数组✅ 插入顺序频繁遍历、按索引访问
LinkedList双向链表✅ 插入顺序频繁头尾插入/删除
HashSetHashMap(key)去重、快速查找
LinkedHashSetLinkedHashMap✅ 插入顺序去重 + 保持顺序
TreeSet红黑树✅ 自然/自定义排序排序去重(如 TopN)
HashMap数组+链表/红黑树key 唯一缓存、映射关系
LinkedHashMapHashMap + 双向链表✅ 插入/访问顺序key 唯一LRU 缓存、JSON 保持字段顺序
TreeMap红黑树✅ key 排序key 唯一范围查询(如 18~30 岁用户)

💡记住:没有“最好”的数据结构,只有“最合适”的!


三、手把手实战:8 大场景精准选型

场景 1:用户 ID 去重(选 HashSet vs ArrayList)

❌ 反例:用 ArrayList 去重
// 错!O(n²) 时间复杂度,数据量大直接卡死 List<Long> userIds = new ArrayList<>(); if (!userIds.contains(userId)) { // contains 是 O(n) userIds.add(userId); }
✅ 正确:用 HashSet
Set<Long> userIds = new HashSet<>(); userIds.add(userId); // 自动去重,O(1) 平均时间

📌原理HashSet底层是HashMap,key 存元素,value 是固定对象。


场景 2:返回用户列表,要求顺序和数据库一致(选 LinkedHashSet)

❌ 反例:用 HashSet,顺序乱了
Set<User> users = new HashSet<>(); users.addAll(dbUsers); // 顺序丢失!前端展示错乱
✅ 正确:用 LinkedHashSet
Set<User> users = new LinkedHashSet<>(); users.addAll(dbUsers); // 保持插入顺序!

✅ 适用:前端需要按“创建时间”顺序展示,且要去重。


场景 3:获取年龄最小的 10 个用户(选 TreeSet)

// 按年龄升序自动排序 Set<User> top10Youngest = new TreeSet<>(Comparator.comparing(User::getAge)); for (User user : allUsers) { top10Youngest.add(user); if (top10Youngest.size() > 10) { top10Youngest.remove(top10Youngest.last()); // 移除最大年龄 } }

💡TreeSet底层是红黑树,插入即排序,适合 TopN、范围筛选。


场景 4:缓存用户信息(选 HashMap vs TreeMap)

❌ 反例:用 TreeMap 查用户(没必要排序)
Map<Long, User> cache = new TreeMap<>(); // O(log n) 查询 User user = cache.get(1001L); // 比 HashMap 慢!
✅ 正确:用 HashMap
Map<Long, User> cache = new HashMap<>(); // O(1) 查询

📌除非需要按 key 排序或范围查询,否则优先 HashMap


场景 5:实现 LRU 缓存(选 LinkedHashMap)

public class LRUCache<K, V> extends LinkedHashMap<K, V> { private final int capacity; public LRUCache(int capacity) { super(capacity, 0.75f, true); // accessOrder=true 表示按访问顺序 this.capacity = capacity; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; // 超过容量自动移除最老元素 } } // 使用 LRUCache<String, String> cache = new LRUCache<>(100); cache.put("user:1001", "张三");

LinkedHashMapaccessOrder=true是实现 LRU 的关键!


场景 6:高频并发读写缓存(选 ConcurrentHashMap)

❌ 反例:用 HashMap + synchronized(性能差)
private final Map<String, Object> cache = new HashMap<>(); public synchronized Object get(String key) { ... } // 整个 map 锁住!
✅ 正确:用 ConcurrentHashMap
private final Map<String, Object> cache = new ConcurrentHashMap<>(); // 无锁读,分段写,高并发神器! Object value = cache.computeIfAbsent(key, k -> loadFromDB(k));

💡 Spring 的@Cacheable默认就用ConcurrentHashMap做本地缓存!


场景 7:队列任务处理(选 ArrayDeque vs LinkedList)

❌ 反例:用 LinkedList 当队列
Queue<Task> queue = new LinkedList<>(); // 内存占用高,缓存不友好
✅ 正确:用 ArrayDeque
Queue<Task> queue = new ArrayDeque<>(); // 数组实现,更快更省内存

📌 Java 官方推荐:优先用ArrayDeque代替StackLinkedList做队列/栈


场景 8:统计词频(选 HashMap + merge)

Map<String, Integer> wordCount = new HashMap<>(); words.forEach(word -> wordCount.merge(word, 1, Integer::sum) // 不存在则设1,存在则+1 );

✅ 比if-else判空简洁 10 倍!


四、Spring Boot 中的经典应用

1. Controller 返回 JSON 字段顺序(用 LinkedHashMap)

@GetMapping("/user") public Map<String, Object> getUser() { // 保证 JSON 字段顺序:id, name, email Map<String, Object> result = new LinkedHashMap<>(); result.put("id", 1001); result.put("name", "张三"); result.put("email", "zhangsan@example.com"); return result; }

否则HashMap可能返回{ "email": "...", "id": 1001, "name": "..." },前端解析混乱。


2. 配置多策略 Bean(用 Map + 策略模式)

@Service public class PaymentContext { // 自动注入所有 PaymentStrategy,key 为 beanName private final Map<String, PaymentStrategy> strategyMap; public PaymentContext(Map<String, PaymentStrategy> strategies) { this.strategyMap = new HashMap<>(strategies); } public void pay(String type, BigDecimal amount) { strategyMap.get(type).pay(amount); // O(1) 查找 } }

这里必须用HashMap,因为要快速根据类型找到策略!


五、避坑指南:常见误区

⚠️ 误区 1:“List 就是 ArrayList”

错!声明时用接口,实现时再选:

List<String> list = new ArrayList<>(); // ✅ ArrayList<String> list = new ArrayList<>(); // ❌ 不利于替换

⚠️ 误区 2:“Set 都是无序的”

错!LinkedHashSetTreeSet都是有序的。

⚠️ 误区 3:“HashMap 线程安全”

大错特错!高并发下HashMap死循环(JDK 7)或数据错乱(JDK 8+)!
并发场景请用ConcurrentHashMap


六、总结:选型决策树

需要去重? ├─ 是 → 需要排序? → 是 → TreeSet │ │ │ └─ 否 → 需要保持插入顺序? → 是 → LinkedHashSet │ └─ 否 → HashSet │ └─ 否 → 需要频繁随机访问? → 是 → ArrayList └─ 否 → 需要频繁头尾操作? → 是 → ArrayDeque / LinkedList

终极口诀

  • 查得快HashMap/HashSet
  • 插得快(头尾)ArrayDeque
  • 要排序TreeMap/TreeSet
  • 要顺序LinkedHashMap/LinkedHashSet
  • 高并发ConcurrentHashMap

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!(发点评论可以给博主加热度哦)

http://www.jsqmd.com/news/322048/

相关文章:

  • 【计算机毕业设计案例】基于springboot+vue的奶茶店线下点餐管理系统基于SpringBoot的奶茶店线上点单与库存管理系统设计与实现(程序+文档+讲解+定制)
  • 线下文档到 AI 知识库(AI-KB):企业内容数字化的新路径
  • 200smart 与威纶通触摸屏实现平面两轴直线插补(Ver1.2.7)
  • 《Nat. Commun.》:南昌大学/宁夏大学团队揭示脉冲加热动力学稳定机制,实现负载金属纳米颗粒的抗烧结锁定
  • 手把手教会你什么是 Spring 事件监听 —— 解耦神器,告别“面条代码”!(Spring Boot 实战)
  • 用户个人资料编辑功能:测试要点、陷阱与最佳实践
  • 机床排屑机厂家报价口碑推荐,选购、运维与售后关键要点分析
  • 2026年1月云真机、云手机、安卓云手机、苹果云手机、ios云手机厂家实力综合分析:天勤网络登顶
  • 订单提交手动测试流程指南
  • Claude Code提示词案例(开发联系我们页面,表单使用Element Plus的el-form组件实现)
  • 2026年 展位设计公司推荐排行榜:主题展位/品牌展位/特装展位/大小面积展位设计搭建,创意视觉与高效落地的专业服务商精选
  • 国内四大AI编程IDE对比(二):从零构建桌面应用实测(补上Trae,幸亏补上了)
  • ACPI!ACPIBuildProcessDeviceGenericEvalStrict函数和BuildRequest->CurrentObject的由来
  • 一个杀手级 prompt
  • Google Genie 3 技术架构拆解:世界模型如何为 Agent 训练提供无限环境
  • threoninamide;DFCYDWOTPTH-NH₂
  • 雨生红球藻主流品牌全景解析(2026年最新版)
  • 基于springboot的电影评价管理系统设计实现
  • 2026年 实验室气路系统厂家推荐排行榜:气体管路、集中供气、汇流排专业解决方案,安全高效精准供气
  • python的crypto模块no model解决方法
  • HTTP 请求方法选择与 RESTful 实践(对比 GraphQL、RPC)
  • mhpkg 文件使用方法
  • 微商企业未来迭代的核心方向与多元探索——以链动2+1模式AI智能名片商城小程序为核心支撑
  • 胡杨映碧水,金沙绕蓝湾,这是罗布湖独有的沙漠浪漫
  • 文件与文件夹批量更名工具FileReNameTool V2.1.1支持撤销改名
  • 2026室内门十大品牌推荐:品质家居的安心之选
  • 写论文软件哪个好?实测5款后,虎贲等考AI凭3大硬核优势封神
  • 期刊论文投稿屡被拒?虎贲等考 AI:从选题到录用的学术发表加速器
  • Java毕设项目推荐-基于Java的饮品店销售管理系统的设计与实现基于SpringBoot的奶茶店线上点单与库存管理系统设计与实现【附源码+文档,调试定制服务】
  • 2026年 展台设计搭建厂家推荐排行榜:全球创意展台、科技感展台、吸睛展台设计公司实力解析与优选指南