商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Java LinkedHashMap与TreeMap示例详解

Java LinkedHashMap与TreeMap示例详解

  发布于2026-06-30 阅读(0)

扫一扫,手机访问

说实话,在学习 Ja va 集合框架时,HashMap 往往是大家最先接触的 Map 实现。但在实际开发里,另外两个“狠角色”——LinkedHashMapTreeMap——同样出场率极高。它们都实现了 Map 接口,但脾性截然不同。

这篇文章会从概念、底层原理、核心差异、适用场景和代码实例这几个维度,帮你把它们彻底吃透。

一、Map 集合基础回顾

Map 就是典型的“键值对(key-value)”数据结构,形如 key → value。例如:"张三" → 18"李四" → 20

Ja va 中常见的 Map 实现大致分三类:

类型特点
HashMap无序
LinkedHashMap有序
TreeMap自动排序

二、LinkedHashMap

1. 什么是 LinkedHashMap

LinkedHashMapHashMap 的子类,它的最大特色就在于——能够完美保持元素的插入顺序。

举个例子:往 Map 里依次放入 1 → A3 → C2 → B,遍历时拿到的顺序依然是 132,绝不会像 HashMap 那样打乱顺序。

2. LinkedHashMap 底层原理

一句话概括:LinkedHashMap = HashMap + 双向链表。

它内部同时保持了 HashMap 的哈希存储结构,以及一个双向链表来维护元素的顺序。整体结构可以理解为:数组 + 链表 + 红黑树 + 双向链表。HashMap 负责高效的查询,双向链表则负责“记住”元素进来的先后顺序。

3. LinkedHashMap 的特点

特点说明
有序按插入顺序排列
查询快基于 HashMap
允许 nullkey 和 value 都允许
非线程安全多线程需额外处理

4. LinkedHashMap 基本使用

示例:保持插入顺序

import ja va.util.LinkedHashMap;
public class Demo {
    public static void main(String[] args) {
        LinkedHashMap map = new LinkedHashMap<>();
        map.put(3, "Ja va");
        map.put(1, "Python");
        map.put(2, "C++");
        System.out.println(map);
    }
}

输出:

{3=Ja va, 1=Python, 2=C++}

可以看到,顺序与插入顺序完全一致。

5. 遍历 LinkedHashMap

import ja va.util.LinkedHashMap;
import ja va.util.Map;
public class Demo {
    public static void main(String[] args) {
        LinkedHashMap map = new LinkedHashMap<>();
        map.put(1, "张三");
        map.put(2, "李四");
        map.put(3, "王五");
        for (Map.Entry entry : map.entrySet()) {
            System.out.println(
                    entry.getKey() + " : " + entry.getValue()
            );
        }
    }
}

输出:

1 : 张三

2 : 李四

3 : 王五

6. LinkedHashMap 的访问顺序

LinkedHashMap 支持两种顺序模式:

顺序说明
插入顺序默认
访问顺序最近访问的排后面

开启访问顺序模式也很简单:

new LinkedHashMap<>(16, 0.75f, true)

第三个参数传 true 就表示开启访问顺序。

示例:LRU缓存思想

import ja va.util.LinkedHashMap;
import ja va.util.Map;
public class Demo {
    public static void main(String[] args) {
        LinkedHashMap map =
                new LinkedHashMap<>(16, 0.75f, true);
        map.put(1, "A");
        map.put(2, "B");
        map.put(3, "C");
        //访问元素
        map.get(1);
        System.out.println(map);
    }
}

输出:

{2=B, 3=C, 1=A}

因为 1 被访问后移动到了末尾,这正是很多缓存系统的核心策略——LRU(最近最少使用)。

三、TreeMap

1. 什么是 TreeMap

TreeMap 最大的特点:自动排序。无论你插入的顺序如何,它都会按照 key 来自动排序。

2. TreeMap 底层原理

TreeMap 底层基于红黑树(Red-Black Tree)实现。红黑树是一种自平衡的二叉搜索树,核心特性很突出:查询效率高、自动排序、增删改效率稳定。

时间复杂度方面:

操作时间复杂度
putO(log n)
getO(log n)
removeO(log n)

3. TreeMap 的特点

特点说明
自动排序按 key 排序
不允许 key 为 null会报空指针异常
查询效率稳定红黑树实现
非线程安全多线程需同步

四、TreeMap 默认排序

默认情况下,TreeMap 会按照 key 的自然顺序进行排序。

示例:数字排序

import ja va.util.TreeMap;
public class Demo {
    public static void main(String[] args) {
        TreeMap map = new TreeMap<>();
        map.put(3, "Ja va");
        map.put(1, "Python");
        map.put(2, "C++");
        System.out.println(map);
    }
}

输出:

{1=Python, 2=C++, 3=Ja va}

即使插入顺序是 312,输出结果仍然是自动排序后的结果。

五、TreeMap 字符串排序

import ja va.util.TreeMap;
public class Demo {
    public static void main(String[] args) {
        TreeMap map = new TreeMap<>();
        map.put("banana", 1);
        map.put("apple", 2);
        map.put("cat", 3);
        System.out.println(map);
    }
}

输出:

{apple=2, banana=1, cat=3}

字符串会按字母顺序进行排序。

六、TreeMap 自定义排序

如果想让 TreeMap 按自己的规则排序,可以使用Comparator 比较器来实现。

示例:降序排序

import ja va.util.Comparator;
import ja va.util.TreeMap;
public class Demo {
    public static void main(String[] args) {
        TreeMap map =
                new TreeMap<>(Comparator.reverseOrder());
        map.put(1, "A");
        map.put(3, "C");
        map.put(2, "B");
        System.out.println(map);
    }
}

输出:

{3=C, 2=B, 1=A}

七、TreeMap 自定义对象排序

如果 key 是自定义对象,那么该对象必须实现 Comparable 接口,或者在构造 TreeMap 时传入一个 Comparator,否则运行时就会报错。

示例:学生年龄排序

Student 类

class Student {
    String name;
    int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return name + "-" + age;
    }
}

使用 Comparator

import ja va.util.Comparator;
import ja va.util.TreeMap;
public class Demo {
    public static void main(String[] args) {
        TreeMap map =
                new TreeMap<>((o1, o2) -> o1.age - o2.age);
        map.put(new Student("张三", 18), "Ja va");
        map.put(new Student("李四", 20), "Python");
        map.put(new Student("王五", 19), "C++");
        System.out.println(map);
    }
}

输出:

{张三-18=Ja va, 王五-19=C++, 李四-20=Python}

八、LinkedHashMap 与 TreeMap 对比

对比项LinkedHashMapTreeMap
是否有序按插入顺序自动排序
底层结构Hash表 + 双向链表红黑树
查询效率O(1)O(log n)
是否允许 null key允许不允许
使用场景记录顺序排序需求

九、如何选择?

使用 LinkedHashMap

  • 需要保持插入顺序
  • 最近访问记录
  • LRU缓存
  • 浏览历史

例如:最近播放歌曲、最近浏览商品等场景。

使用 TreeMap

  • 自动排序
  • 排行榜
  • 成绩排序
  • 字典排序

例如:学生成绩排名、商品价格排序等场景。

十、小tips

1. LinkedHashMap 和 HashMap 区别?

LinkedHashMap 是有序的,内部多了一个双向链表;而 HashMap 是无序的,纯哈希结构。

2. TreeMap 为什么能排序?

因为底层是红黑树,插入元素时会自动比较 key,从而实现排序。

3. TreeMap 为什么不能为 null?

因为排序时需要调用 compareTo() 方法来比较 key,而 null 无法被比较,会直接抛出空指针异常。

4. LinkedHashMap 为什么适合做缓存?

因为它支持访问顺序这种模式:最近访问的数据会自动移动到链表尾部。这正好符合 LRU(最近最少使用)缓存淘汰策略。

十一、总结

LinkedHashMap

核心关键词:有序、插入顺序、双向链表、缓存。适合那种既想要 HashMap 的高效查询,又需要保持元素顺序的场景。

TreeMap

核心关键词:自动排序、红黑树、比较器、有序Map。适合那些需要按 key 自动排序的场景。

十二、用一张图来表示三种map

Map
├── HashMap
│     ├── 无序
│     └── 查询快
│
├── LinkedHashMap
│     ├── 有序
│     ├── 双向链表
│     └── 适合缓存
│
└── TreeMap
      ├── 自动排序
      ├── 红黑树
      └── 适合排行榜

真正掌握集合框架后,其实我们会发现:Ja va 集合本质就是“数据结构 + 算法思想”的具体实现。

本文转载于:https://www.jb51.net/program/364794nu9.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注