【TreeMap】-根据 key 或 value 排序

2023-11-04

1. 根据 key 排序

引言

  • TreeMap 中key 可以自动String 类型或8大基本类型的包装类型进行排序
  • 但是,TreeMap 无法直接自定义类型进行排序。
  • 当我们想对对 TreeMapkey 中的自定义类型排序时,必须要指定**排序规则。主要有两种解决方案**:

根据 key 排序,主要有两种方法

  1. 方法1:实现 Comparator 接口,并传递给 TreeMap 构造器;
  2. 方法2:使得 key 对应类 implements Comparable接口

两种排序规则如何选择呢?

  • 当比较规则不会发生改变的时候,或者说比较规则只有一个的时候,建议实现 Comparable 接口;
  • 比较规有多个,并且需要在多个比较规则之间频繁切换时,建议使用 Comparator 比较器。

方法1:实现 Comparator 接口

import java.util.*;

class Solution {
    public static void main(String[] args) {
        Map<Person, String> map = new TreeMap<>((person1, person2) -> {
            // 先按照age降序排序
            if (person1.getAge() - person2.getAge() != 0) {
                return person2.getAge() - person1.getAge();
            }
            // age相同时,按照name升序排序
            return person1.getName().compareTo(person2.getName());
        });
        map.put(new Person("zhangsan", 15), "001");
        map.put(new Person("lisi", 18), "002");
        map.put(new Person("wangwu", 20), "003");
        map.put(new Person("zhaoliu", 18), "004");
        map.put(new Person("ouyangfeng", 60), "006");
        map.put(new Person("hongqigong", 60), "005");

        System.out.println("排序后,map = ");
        for (Map.Entry<Person, String> entry : map.entrySet()) {
            System.out.println(entry);
        }
    }
}

class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name = " + name +
                ", age = " + age +
                '}';
    }
}

运行结果如下:
在这里插入图片描述

方法2:implements Comparable

import java.util.*;

class Solution {
    public static void main(String[] args) {
        Map<Person, String> map = new TreeMap<>();
        map.put(new Person("zhangsan", 15), "001");
        map.put(new Person("lisi", 18), "002");
        map.put(new Person("wangwu", 20), "003");
        map.put(new Person("zhaoliu", 18), "004");
        map.put(new Person("ouyangfeng", 60), "006");
        map.put(new Person("hongqigong", 60), "005");

        System.out.println("排序后,map = ");
        for (Map.Entry<Person, String> entry : map.entrySet()) {
            System.out.println(entry);
        }
    }
}

// 
class Person implements Comparable<Person> {
    private String name;
    private int age;

    @Override
    public int compareTo(Person person) {
        // 先按照age降序排序
        if (this.getAge() - person.getAge() != 0) {
            return person.getAge() - this.getAge();
        }
        // age相同时,按照name升序排序
        return this.getName().compareTo(person.getName());
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name = " + name +
                ", age = " + age +
                '}';
    }
}

2. 根据 value 排序

同上根据 key 排序,根据 value 排序时,也可以有两种方法,这里仅仅展示“实现Comparator接口”的方法

map 根据 value 排序时,和根据 key 排序相比 较为繁琐,具体步骤如下:

  1. map.entrySet() 转存至 list,即 lsit 中每个元素的类型为 Map.Entry
  2. 利用 Collections.sort 根据 listertry.getValue() 进行排序;
  3. “实现Comparator接口”,自定义 ertry.getValue() 的排序规则
import java.util.*;

class Solution {
    public static void main(String[] args) {
        Map<String, Person> map = new HashMap<>();
        map.put("001", new Person("zhangsan", 15));
        map.put("002", new Person("lisi", 18));
        map.put("003", new Person("wangwu", 20));
        map.put("004", new Person("zhaoliu", 18));
        map.put("006", new Person("ouyangfeng", 60));
        map.put("005", new Person("hongqigong", 60));
        System.out.println("排序前,map = " );
        for (Map.Entry<String, Person> entry : map.entrySet()) {
            System.out.println(entry);
        }

        // 1、map to list
        List<Map.Entry<String, Person>> entries = new ArrayList<>(map.entrySet());
        // 2、重写排序规则
        Collections.sort(entries, (entry1, entry2) -> {
            Person person1 = entry1.getValue();
            Person person2 = entry2.getValue();
            // 先按照age降序排序
            if (person1.getAge() - person2.getAge() != 0) {
                return person2.getAge() - person1.getAge();
            }
            // age相同时,按照name升序排序
            return person1.getName().compareTo(person2.getName());
        });

        System.out.println("\n排序后,entries = ");
        for (Map.Entry<String, Person> entry : entries) {
            System.out.println(entry);
        }
    }
}

class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name = " + name +
                ", age = " + age +
                '}';
    }
}

运行结果如下:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【TreeMap】-根据 key 或 value 排序 的相关文章

  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • 如何使用 Java 和 Selenium WebDriver 在 C 目录中创建文件夹并需要将屏幕截图保存在该目录中?

    目前正在与硒网络驱动程序和代码Java 我有一种情况 我需要在 C 目录中创建一个文件夹 并在该文件夹中创建我通过 selenium Web 驱动程序代码拍摄的屏幕截图 它需要存储在带有时间戳的文件夹中 如果我每天按计划运行脚本 所有屏幕截
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo

随机推荐

  • vue+element ui 中国标准化时间转换日期多种格式

    vue element ui 中国标准化时间转换日期多种格式 最近在做项目的时候用到了DatePicker 日期选择器 结果选好日期获取日期value得到这个玩意儿 有点恶心的中国标准化时间 如果想要转化成2021 04 3或 2021 0
  • 解决 Spring Cloud 部分版本,使用 nacos 做配置中心,报 No spring.config.import property has been defined 的问题

    报错信息如下 Description No spring config import property has been defined Spring 官方给出的解决方案如下 Add a spring config import nacos
  • Spring Cloud服务框架版本升级--JDK10+Gradle4.9+Spring Boot 2.0+Finchley.SR1

    目标 原有版本升级为Spring Boot 2 0与Spring Cloud Finchley SR1 使用gradle管理工程 搭建注册 配置 网关与追踪框架 加入k8s api微服务 环境 IntelliJ IDEA 步骤 版本升级及其
  • 大数据毕业设计 电商用户行为数据分析可视化 - python

    文章目录 0 前言 一 背景描述 二 项目背景 三 数据来源 四 提出问题 五 理解数据 六 数据清洗 6 1缺失值处理 6 2查看数据 6 3一致化处理 6 4查看data user数据集数据类型 6 5数据类型转换 6 6异常值处理 七
  • 对接微信支付接口开发详细步骤

    1 第一步 我们需要从哪里入手 当然我们需要有微信商家账号怎样申请商家账号呢 当然还是需要有一个已经审核过的微信公众号 这样的话 首先你必须先有个审核通过的微信公众号 这里就不说怎么审核公众号了这个公众号比较好弄 如何申请微信商户号 如图
  • ORA-01578的处理

    某天一台数据库测试机出现 ORA 01578 虽说这是测试机但是这是客户用的 随便处理也不行 仔细研究一下 ORA 01578 ORACLE data block corrupted file 2 block 69449 ORA 01110
  • LeetCode(Python)—— 只出现一次的数字(简单)

    只出现一次的数字 概述 给定一个非空整数数组 除了某个元素只出现一次以外 其余每个元素均出现两次 找出那个只出现了一次的元素 你的算法应该具有线性时间复杂度 你可以不使用额外空间来实现吗 输入 2 2 1 输出 1 输入 4 1 2 1 2
  • [机缘参悟-77]:深度思考-《天道》中强势文化、弱势文化与人的行为模式的关系

    目录 一 文化属性与人的行为模式 二 强势文化与弱势文化 2 1 弱势文化的本质与其行为模式 2 2 强势文化的本质与其行为模式 三 强势文化造就强者 弱势文化造就弱者 一 文化属性与人的行为模式 文化 是一个广义词 它的概括面相当的广泛
  • 二分查找算法及其实例

    二分查找算法及其实例 问题一 二分查找 给定一个 n 个元素有序的 升序 整型数组 nums 和一个目标值 target 写一个函数搜索 nums 中的 target 如果目标值存在返回下标 否则返回 1 示例 1 输入 nums 1 0
  • Win7连接网络打印机步骤

    Win7客户端添加网络打印机 1 进入打印机官网 先下载对应型号的打印机驱动 2 找到控制面板 gt 点击硬件和声音 gt 设备和打印机 3 点击添加打印机按钮 选择添加网络 无线或Bluetooth打印机 4 搜索可用的打印机 5 找到对
  • 2023中国民营100强投资趋势

    导读 根据民企注册地了解到 民企100强企业几乎一半分布在华东地区 其次分布在华南 华北和华中地区 从省份来看 广东 浙江是主要分布的省份 企业数量分别是19家 江苏省有14家 北京市有8家 上海市有7家 河北省 山东省各6家 关注公众号
  • taro生命周期详解

    taro生命周期详解 taro介绍 生命周期 react的钩子函数 为兼容小程序的钩子函数 个别生命周期详解以及注意 1 render 函数 2 constructor 构造函数 3 在各个生命周期钩子函数中修改state的属性或者参数 4
  • 华为OD机试真题 (python)之支持优先级的队列

    题目描述 支持优先级的队列 实现一个支持优先级的队列 高优先级先出队列 同优先级时先进先出如果两个输入数据和优先级都相同 则后一个数据不入队列被丢弃 队列存储的数据内容是一个整数 输入描述 组待存入队列的数据 包含内容和优先级 输出描述 队
  • java corn 定时任务调度,每分钟执行一次,每半个小时执行一次

    java corn 表达式 每分钟执行一次 Scheduled cron 0 1 每半个小时执行一次 Scheduled cron 0 0 30 springboot 类 EnableScheduling Configuration Slf
  • 自定义截图方法,如何在RobotFrameWork的日志中显示

    用RobotFrameWork做UI自动化时 一般初学者都会选择第三方扩展库SeleniumLibrary进行UI自动化测试 随然已经封装许多浏览器操作方法 但在实际应用 某些方法还是不能满足我们的需求 于是乎 我们就舍弃SeleniumL
  • 以服务方式启动安防监控系统EasyNVR程序出现播放异常,是什么原因?

    EasyNVR安防视频监控平台的特点是基于RTSP Onvif协议 将前端设备统一接入 在平台进行转码 直播 处理及分发 在智慧安防视频监控场景中 EasyNVR可实现实时监控 云端录像 检索与回放 云存储 告警 级联等视频能力 极大满足行
  • 1.2 Ubauntu 使用

    一 完成VMware Tools安装 双击 VMwareTool 打开 Ubuntu 终端快捷键 Alt Control T 切换汉语的快捷键是Alt 空格 ls 打印出当前所在目录中所有文件和文件夹 cd 桌面 进入桌面文件夹 sudo
  • java生成有理数_第四届蓝桥杯Java B——有理数类

    有理数就是可以表示为两个整数的比值的数字 一般情况下 我们用近似的小数表示 但有些时候 不允许出现误差 必须用两个整数来表示一个有理数 这时 我们可以建立一个 有理数类 下面的 class Rational private long ra
  • Python-使用空值进行赋值-None

    0 摘要 在Python中 尤其是数组当中 对于一些异常值往往需要进行特殊处理 为了防止异常值与正常数据混淆 影响最终计算结果 常用的方法是将异常值置零或者置空 置零的方法较为简单 本文主要介绍如果对python中的数据进行置空 1 赋值为
  • 【TreeMap】-根据 key 或 value 排序

    1 根据 key 排序 引言 TreeMap 中key 可以自动对 String 类型或8大基本类型的包装类型进行排序 但是 TreeMap 无法直接对自定义类型进行排序 当我们想对对 TreeMap 中 key 中的自定义类型排序时 必须