Java TreeMap:基于红黑树的排序映射解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Java TreeMap:基于红黑树的排序映射解析

在Java的集合框架中,TreeMap是一个非常重要的成员,它实现了SortedMap接口,为键(Key)提供了一个有序的映射。这种有序性是通过红黑树数据结构来实现的,红黑树是一种自平衡的二叉查找树,它能够在最坏的情况下保证基本的动态集合操作(如查找、插入和删除)的时间复杂度仍然是对数的。


1. TreeMap概述


TreeMap存储的键值对默认是按照键的自然顺序进行排序的,也可以根据创建TreeMap时提供的Comparator进行排序。这意味着当你遍历TreeMap时,你会得到一个按键排序的键值对序列。


2. TreeMap的内部结构


红黑树TreeMap实现有序性的关键。红黑树的特性确保了树的平衡,从而在插入、删除和查找操作时都能保持对数级别的时间复杂度。红黑树的每个节点都有一个颜色属性——红色或黑色,并且满足以下性质:

  • 每个节点或是红色,或是黑色。
  • 根节点是黑色。
  • 每个叶子节点(NIL节点,空节点)是黑色。
  • 如果一个节点是红色的,则它的两个子节点都是黑色的。
  • 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

这些性质确保了树的高度相对较低,从而优化了性能。


3. TreeMap的使用场景


  • 当你需要一个有序的键值对集合时。
  • 当你需要对键进行范围查询时(例如查找所有键在指定范围内的元素)。
  • 当你需要一个能够在插入和删除时保持高效性能的数据结构时。


4. 示例代码


下面是一个简单的示例,展示了如何使用TreeMap

import java.util.TreeMap;
public class TreeMapExample {
    public static void main(String[] args) {
        // 创建一个TreeMap实例,按照键的自然顺序排序
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        
        // 向TreeMap中添加元素
        treeMap.put("apple", 1);
        treeMap.put("orange", 2);
        treeMap.put("banana", 3);
        treeMap.put("pear", 4);
        
        // 遍历并打印TreeMap中的元素(按键的顺序)
        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        
        // 根据键的范围查询元素(包含起始键,不包含结束键)
        TreeMap<String, Integer> subMap = (TreeMap<String, Integer>) treeMap.subMap("apple", "pear");
        System.out.println("Elements between 'apple' and 'pear':");
        for (Map.Entry<String, Integer> entry : subMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

输出:

apple: 1
banana: 3
orange: 2  # 注意这里的顺序,因为按照字母顺序排序了键
pear: 4    # 同上,尽管在插入时pear是在orange后面的,但在排序后它的顺序改变了
Elements between 'apple' and 'pear':  # 范围查询结果不包括'pear'键对应的元素
apple: 1
banana: 3  # 注意这里只有banana是因为orange不在apple和pear之间(按照字母顺序)

注意:在上面的输出中,你可能会注意到“orange”和“banana”的顺序似乎与插入顺序不同。这是因为TreeMap默认按键的自然顺序(这里是字母顺序)对键进行排序,而不是按照插入顺序。此外,范围查询的结果也是有序的,并且不包括结束键对应的元素。如果你想按照特定的顺序对键进行排序,可以在创建TreeMap时提供一个自定义的Comparator


5. 自定义排序


为了按照自定义的顺序对TreeMap中的键进行排序,可以在创建时传入一个Comparator对象:

import java.util.Comparator;
import java.util.TreeMap;
public class CustomSortedTreeMap {
    public static void main(String[] args) {
        // 创建一个自定义排序的TreeMap实例(按照字符串长度排序)
        TreeMap<String, Integer> treeMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(o1.length(), o2.length());
            }
        });
        
        // 向TreeMap中添加元素并打印(按键的长度顺序)
        treeMap.put("apple", 1);  // 长度为5的键
        treeMap.put("kiwi", 2);   // 长度为4的键
        treeMap.put("pear", 3);   // 长度为4的键
        treeMap.put("banana", 4); // 长度为6的键,会被放在最后面即使它是先被插入的
        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

在这个例子中,我们提供了一个自定义的Comparator来按照字符串的长度对键进行排序。因此,“kiwi”和“pear”(长度为4)将出现在“apple”(长度为5)之前,“banana”(长度为6)将出现在最后,即使它是第一个被插入的元素。

相关文章
|
20天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
89 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
6天前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
94 11
|
5天前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
28 7
|
Java
Java实现红黑树
红黑树概要 二叉查找树实现了基本操作时间复杂度O(h),但是树的高度h在最坏的情况下可能变为n 红黑树是一种平衡二叉树,可以保证树的高度 h = lg(N) 红黑树的性质 红黑树为每个节点添加了颜色存储位,确保了任何一个从根到叶子的路径长度不会比其他路径长出2倍 每个节点是红色或者黑色 根节点是黑色的 叶子节点是黑色的 红色节点的子节点都是黑色的 当前节点到其后代叶子节点的所有简单路径路的黑色节点数目相同 性质4确保了根节点到任意叶子节点的路径长度不会比到其他叶子节点的路径长度长出2倍。
969 0
|
14天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
69 17
|
25天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
10天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
27天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
27天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
27天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
54 3

热门文章

最新文章

推荐镜像

更多