news 2026/4/3 6:30:01

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/2 2:12:58

潜伏在施工一线的健康杀手—灰尘

万丈高楼平地起&#xff0c;城市发展的同时&#xff0c;建筑工地扬尘问题日益突出。施工过程中产生的灰尘&#xff0c;看似微不足道&#xff0c;却能轻易突破人体呼吸防线&#xff0c;对呼吸道和肺部造成持续损害&#xff0c;成为潜藏在身边的健康隐患。因此&#xff0c;做好呼…

作者头像 李华
网站建设 2026/4/2 1:21:08

PPIO 上线 PaddleOCR-VL-1.5 :小参数高性能 | 一键部署

PPIO 算力市场首发上线了 PaddleOCR-VL-1.5 模型模板。作为 PaddleOCR-VL 系列的全新迭代版本&#xff0c;PaddleOCR-VL-1.5 在保持 0.9B 轻量级参数的同时&#xff0c;性能实现了显著提升 。在权威评测集 OmniDocBench v1.5 上&#xff0c;该模型取得了 94.5% 的精度&#xff…

作者头像 李华
网站建设 2026/3/13 6:01:58

标针冲压工艺及模具设计

标针冲压工艺及模具设计 一、设计背景与意义 标针作为电子设备、仪器仪表、医疗器械等领域的核心精密零件&#xff0c;具有尺寸小、精度要求高&#xff08;公差≤0.02mm&#xff09;、批量需求大等特点。传统加工方式采用切削加工&#xff0c;存在效率低、成本高、材料浪费严…

作者头像 李华
网站建设 2026/3/26 11:47:36

2026网络安全核心技术栈与实战学习指南

2026网络安全核心技术栈与实战学习指南 随着数字化转型的深化&#xff0c;网络攻击手段持续迭代&#xff0c;从传统的漏洞利用、暴力破解&#xff0c;到新型的AI驱动攻击、供应链攻击&#xff0c;网络安全已成为企业数字化发展的“生命线”。对技术从业者而言&#xff0c;掌握…

作者头像 李华
网站建设 2026/4/3 4:16:36

手机端pdf转word,免费工具随时随地转

theme: default themeName: 默认主题 需要立刻在手机上把pdf转为word文件吗&#xff0c;免费工具让这成为可能&#xff0c;你可以不用电脑就修改合同&#xff0c;简历或报告&#xff0c;本文探讨了适用于iphone和android的简单免费应用&#xff0c;我们看看它们如何工作&#x…

作者头像 李华