Java 数据结构详解

Java 数据结构详解

Java 数据结构详解

Java 数据结构是 Java 编程中存储和组织数据的方式,就像现实生活中 “书架”“抽屉”“字典” 等工具 —— 不同的结构适合存放不同类型的数据,也决定了 “存、取、查” 的效率。Java 内置了一套完善的集合框架(Collection Framework),把常用数据结构封装成了易用的类,我们不需要从零实现,直接拿来用就行。

一、先搞懂:Java 集合框架的 “家谱”

Java 集合框架就像一个大家族,主要分为两大分支:

单值集合(Collection):每个元素是单个值(如数字、字符串),包括 List(有序可重复)、Set(无序不可重复);

键值对集合(Map):每个元素是 “键 - 值” 对(如字典中的 “单词 - 解释”),代表是 Map 接口。

它们的关系可以简单理解为:

集合框架

├─ Collection(单值集合)

│ ├─ List(有序、可重复)

│ │ ├─ ArrayList(数组实现)

│ │ └─ LinkedList(链表实现)

│ └─ Set(无序、不可重复)

│ ├─ HashSet(哈希表实现)

│ └─ TreeSet(红黑树实现,有序)

└─ Map(键值对集合)

├─ HashMap(哈希表实现)

└─ TreeMap(红黑树实现,键有序)

二、单值集合(Collection)详解

1. List:有序可重复的 “数组增强版”

List 就像一排有编号的抽屉,每个抽屉有固定位置(索引),可以放相同的东西(可重复)。你可以通过编号快速找到某个抽屉,也可以在任意位置添加 / 删除抽屉。

常用实现类:

ArrayList:底层是动态数组(长度可变的数组)。

优点:通过索引(如 get(0))访问元素极快(时间复杂度 O (1));

缺点:在中间插入 / 删除元素慢(需要移动后面的元素,时间复杂度 O (n));

类比:像一本书,查第 100 页很快,但在第 50 页插入一页,后面的页码都要变。

代码示例:

import java.util.ArrayList;

import java.util.List;

public class Test {

public static void main(String[] args) {

List list = new ArrayList<>();

// 添加元素

list.add("苹果");

list.add("香蕉");

list.add("苹果"); // 允许重复

// 按索引访问(0 开始)

System.out.println(list.get(1)); // 输出:香蕉

// 遍历

for (String fruit : list) {

System.out.println(fruit); // 输出:苹果、香蕉、苹果(顺序和添加一致)

}

}

}

LinkedList:底层是双向链表(每个元素像 “铁链” 一样连在一起,每个节点记录前后节点的位置)。

优点:在中间插入 / 删除元素快(只需改前后节点的链接,时间复杂度 O (1));

缺点:通过索引访问慢(需要从头遍历到目标位置,时间复杂度 O (n));

类比:像一串项链,拆中间的珠子只需解开两边的线,但要找第 100 颗珠子,得从第一颗开始数。

2. Set:无序不可重复的 “去重神器”

Set 就像一个没有编号的袋子,里面的元素没有固定顺序,且不能有重复(比如 “黑名单” 里不能有重复的名字)。

常用实现类:

HashSet:底层是哈希表(通过 “哈希值” 快速定位元素)。

特点:无序(遍历顺序和添加顺序可能不同)、去重(依赖元素的 hashCode() 和 equals() 方法);

优点:添加、删除、查询速度极快(时间复杂度 O (1));

类比:像一本字典,通过拼音首字母(哈希值)快速找到单词,且不会有重复的单词。

代码示例:

import java.util.HashSet;

import java.util.Set;

public class Test {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add("苹果");

set.add("香蕉");

set.add("苹果"); // 重复元素,会被自动过滤

// 遍历(顺序不确定)

for (String fruit : set) {

System.out.println(fruit); // 输出:苹果、香蕉(无重复)

}

}

}

TreeSet:底层是红黑树(一种自平衡的排序树)。

特点:自动按元素大小排序(如数字从小到大、字符串按字典序)、去重;

优点:适合需要 “排序 + 去重” 的场景(如排行榜);

缺点:添加 / 查询速度比 HashSet 稍慢(时间复杂度 O (log n))。

三、键值对集合(Map):像字典一样 “通过键找值”

Map 存储的是 “键(Key)- 值(Value)” 对,就像字典中 “单词(键)- 解释(值)” 的对应关系。键不能重复(一个单词只能有一个解释),但值可以重复(多个单词可以有相同解释)。

常用实现类:

HashMap:底层是哈希表(数组 + 链表 / 红黑树)。

特点:键无序、键唯一;

优点:根据键查询值的速度极快(O (1)),适合频繁的 “存、取” 操作;

类比:像手机通讯录,通过姓名(键)快速找到电话(值),姓名不能重复。

代码示例:

import java.util.HashMap;

import java.util.Map;

public class Test {

public static void main(String[] args) {

Map scoreMap = new HashMap<>();

// 存键值对

scoreMap.put("张三", 90);

scoreMap.put("李四", 85);

scoreMap.put("张三", 95); // 键重复,会覆盖之前的值

// 查值(通过键)

System.out.println(scoreMap.get("李四")); // 输出:85

// 遍历所有键值对

for (Map.Entry entry : scoreMap.entrySet()) {

System.out.println(entry.getKey() + ":" + entry.getValue());

// 输出:张三:95、李四:85(顺序不确定)

}

}

}

TreeMap:底层是红黑树。

特点:键会自动按大小排序(如数字键从小到大);

适合场景:需要按键排序的场景(如按学号排序的成绩表)。

四、其他常用数据结构

除了上述核心集合,Java 中还有一些特殊结构:

Queue(队列):“先进先出”(FIFO)的结构,像排队买票,先到先得。常用实现 LinkedList(因为链表适合频繁添加 / 删除)。

Queue queue = new LinkedList<>();

queue.offer("第一个人"); // 入队

queue.offer("第二个人");

System.out.println(queue.poll()); // 出队:第一个人(先入先出)

Stack(栈):“后进先出”(LIFO)的结构,像叠盘子,最后放的先拿走。Java 中常用 Deque 替代(LinkedList 实现)。

Deque stack = new LinkedList<>();

stack.push("第一层盘子"); // 入栈

stack.push("第二层盘子");

System.out.println(stack.pop()); // 出栈:第二层盘子(后入先出)

数组(Array):最基础的线性结构,长度固定,通过索引访问快,但不能动态扩容(ArrayList 是对数组的 “动态扩容” 封装)。

五、如何选择合适的数据结构?

记住几个核心场景:

需有序 + 可重复 + 频繁查:用 ArrayList;

需有序 + 可重复 + 频繁增删中间元素:用 LinkedList;

需去重 + 无序:用 HashSet;

需去重 + 排序:用 TreeSet;

需键值对 + 无序:用 HashMap;

需键值对 + 键排序:用 TreeMap;

需先进先出:用 Queue(LinkedList 实现);

需后进先出:用 Deque 当栈(LinkedList 实现)。

总结

Java 数据结构的核心是集合框架,它把复杂的底层实现(数组、链表、哈希表、红黑树等)封装成简单的类,我们只需关注 “用什么结构” 和 “怎么用”。

posted on

2025-08-29 09:10

coding博客

阅读(66)

评论(0)

收藏

举报

相关风雨