Java LinkedHashMap与TreeMap示例详解

 更新时间:2026年05月29日 09:41:18   作者:一条泥憨鱼  
本文对比分析了Java中LinkedHashMap和TreeMap两种Map实现类的特性与使用场景,本文结合实例代码给大家介绍给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

前言:

在学习 Java 集合框架时,很多同学已经接触过 HashMap
但在实际开发中,我们还会经常遇到另外两种 Map:

  • LinkedHashMap
  • TreeMap

它们都属于 Map 接口的实现类,但各自有不同的特点和使用场景。

这篇文章会从:

  • 基本概念
  • 底层原理
  • 特点区别
  • 使用场景
  • 代码实例

几个方面,帮你彻底理解它们。

一、Map 集合基础回顾

Map 是“键值对(key-value)”结构的数据集合。

格式:

key -> value

例如:

"张三" -> 18
"李四" -> 20

Java 中常见的 Map:

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

二、LinkedHashMap

1. 什么是 LinkedHashMap

LinkedHashMapHashMap 的子类。

它最大的特点:

能够保持元素的插入顺序。

例如:

1 -> A
3 -> C
2 -> B

遍历时仍然是:

1
3
2

不会像 HashMap 一样顺序混乱。

2. LinkedHashMap 底层原理

LinkedHashMap = HashMap + 双向链表

它内部:

  • 使用 HashMap 进行存储
  • 使用双向链表维护顺序

结构示意:

数组 + 链表 + 红黑树 + 双向链表

其中:

  • HashMap 保证查询效率
  • 双向链表保证顺序

3. LinkedHashMap 的特点

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

4. LinkedHashMap 基本使用

示例:保持插入顺序

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

输出:

{3=Java, 1=Python, 2=C++}

可以发现:

顺序与插入顺序一致。

5. 遍历 LinkedHashMap

import java.util.LinkedHashMap;
import java.util.Map;
public class Demo {
    public static void main(String[] args) {
        LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
        map.put(1, "张三");
        map.put(2, "李四");
        map.put(3, "王五");
        for (Map.Entry<Integer, String> 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 java.util.LinkedHashMap;
import java.util.Map;
public class Demo {
    public static void main(String[] args) {
        LinkedHashMap<Integer, String> 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

被访问后移动到了最后,这就是很多缓存系统的核心思想。

三、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 默认排序

默认按照 key 的自然顺序排序。

示例:数字排序

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

输出:

{1=Python, 2=C++, 3=Java}

即使插入顺序:

3 1 2

结果仍然自动排序。

五、TreeMap 字符串排序

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

输出:

{张三-18=Java, 王五-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?

因为排序时需要比较 key:

compareTo()

null 无法比较。

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

因为它支持:

访问顺序

最近访问的数据会移动到尾部。

这正符合:

LRU(使用少)

缓存淘汰策略。

十一、总结

LinkedHashMap

核心关键词:

有序
插入顺序
双向链表
缓存

适合:

既想要 HashMap 的效率,又想保持顺序。

TreeMap

核心关键词:

自动排序
红黑树
比较器
有序Map

适合:

需要按 key 自动排序的场景。

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

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

真正掌握集合框架后,其实我们会发现:

Java 集合本质就是:

“数据结构 + 算法思想” 的具体实现。

到此这篇关于Java LinkedHashMap与TreeMap的文章就介绍到这了,更多相关Java LinkedHashMap与TreeMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java使用lambda自定义Arrays.sort排序规则说明

    Java使用lambda自定义Arrays.sort排序规则说明

    这篇文章主要介绍了Java使用lambda自定义Arrays.sort排序规则说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 在Filter中不能注入bean的问题及解决

    在Filter中不能注入bean的问题及解决

    这篇文章主要介绍了在Filter中不能注入bean的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • SpringBoot使用TraceId进行日志链路追踪的实现步骤

    SpringBoot使用TraceId进行日志链路追踪的实现步骤

    有时候一个业务调用链场景,很长,调了各种各样的方法,看日志的时候,各个接口的日志穿插,确实让人头大,所以为了解决这个问题,本文给大家介绍了SpringBoot使用TraceId进行日志链路追踪的实现步骤,需要的朋友可以参考下
    2024-11-11
  • Java多线程编程安全退出线程方法介绍

    Java多线程编程安全退出线程方法介绍

    这篇文章主要介绍了Java多线程编程安全退出线程方法介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • SpringBoot中开启Gzip压缩的两种方式详解

    SpringBoot中开启Gzip压缩的两种方式详解

    随着互联网应用的飞速发展,数据传输的效率和性能成为了至关重要的问题,对于基于SpringBoot框架构建的WebGIS应用来说,如何高效地传输数据、减少网络带宽的占用,是提升用户体验和系统性能的关键所在,而Gzip压缩技术,作为一种被广泛采用的解决方案,下面给大家详细介绍一下
    2025-09-09
  • Java实现饼图旋转角度的代码详解

    Java实现饼图旋转角度的代码详解

    在现代数据可视化领域,饼图因其直观展示各部分占整体比例而被广泛采用,为了增强互动性和吸引力,常会赋予饼图 旋转 动画:自动、平滑地旋转,让用户从不同角度重点查看扇区,本文将从零开始,手把手实现一个 Java2D Swing 版 的 可旋转饼图组件,需要的朋友可以参考下
    2025-05-05
  • Springmvc应用Mongodb分页实现

    Springmvc应用Mongodb分页实现

    这篇文章主要为大家详细介绍了Springmvc应用Mongodb分页实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • SpringBoot 使用jwt进行身份验证的方法示例

    SpringBoot 使用jwt进行身份验证的方法示例

    这篇文章主要介绍了SpringBoot 使用jwt进行身份验证的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • java如何获取本机IP地址

    java如何获取本机IP地址

    这篇文章主要为大家详细介绍了java如何获取本机IP地址,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Java Servlet3.0异步处理问题

    Java Servlet3.0异步处理问题

    这篇文章主要介绍了Java中Servlet3.0异步处理的原理以及遇到的问题分析,需要的朋友参考一下。
    2017-12-12

最新评论