【日常记录】关于LinkedHashMap中key为数字字符串根据compareTo排序的问题

本文主要是介绍【日常记录】关于LinkedHashMap中key为数字字符串根据compareTo排序的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天在修复Bug的时候,在项目中发现有这样一段代码(为了方便,下面用一个例子进行演示)。
项目中使用了LinkedHashMap key为Long类型,value为String类型。
并且,LinkedHashMap 使用Stream流 对key进行升序的排列,看了代码貌似没有什么问题。

  LinkedHashMap<Long, String> linkedHashMap = new LinkedHashMap<>();linkedHashMap.put(12L, "测试1");linkedHashMap.put(26L, "测试2");linkedHashMap.put(8L, "测试3");linkedHashMap.put(120L, "测试4");linkedHashMap.put(4L, "测试5");LinkedHashMap<Long, String> resLinkHashMap = linkedHashMap.entrySet().stream().sorted((o1, o2) -> {String key1 = o1.getKey().toString();String key2 = o2.getKey().toString();return key1.compareTo(key2);}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));System.out.println("resLinkHashMap = " + resLinkHashMap);

运行后结果是这样的:

resLinkHashMap = {12=测试1, 120=测试4, 26=测试2, 4=测试5, 8=测试3}

发现结果并没有按照key进行从小到大的规则进行排序。
于是下面分析了String中的compareTo方法 排序规则到底是怎样的,特地记录一下:

在Java中,我们通常使用String类的compareTo()函数来比较两个字符串的大小。compareTo()函数返回一个整数值,用于表示两个字符串的大小关系。

String 类 compareTo() 方法按字典顺序将给定字符串与当前字符串进行比较。它是根据字符串中每个字符的 Unicode 值比较字符串的,它返回正数、负数或 0。

比较规则如下:

  • 如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值。

  • 如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符作比较,也是返回差值。

  • 由此此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度,返回他们长度的差值。

从源码角度分析compareTo()方法:
JDK 1.8 源码分析
知道了上述的排序规则后,我们进行简单测试下:

        int i = "10".compareTo("3");System.out.println("i = " + i);

i = -2

根据返回排序规则,上面返回了-2 ,是字符 1、字符3 的ASCII的值: 65 - 67 = -2 的结果,结果却小于0。 导致10 < 3。这就是上面LinkedHashMap 根据key 转化为String 后使用compareTo 排序的问题所在。

注意:对于字符串长度不能的数字字符串不能使用compareTo进行比较。

对上面的排序方法进行修改如下:

        LinkedHashMap<Long, String> resLinkHashMap = linkedHashMap.entrySet().stream().sorted(Comparator.comparingInt(o -> o.getKey().intValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));System.out.println("resLinkHashMap = " + resLinkHashMap);

resLinkHashMap = {4=测试5, 8=测试3, 12=测试1, 26=测试2, 120=测试4}

这篇关于【日常记录】关于LinkedHashMap中key为数字字符串根据compareTo排序的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/349498

相关文章

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的