源码解析Collections.sort ——从一个逃过单测的 bug 说起

2023-11-11

本文从一个小明写的bug 开始,讲bug的发现、排查定位,并由此展开对涉及的算法进行图解分析和源码分析。

事情挺曲折的,因为小明的代码是有单测的,让小明更加笃定自己写的没问题。所以在排查的时候,也经历了前世的500年,去排查排序后的list改动(主要是小明和同事互相怀疑对方的代码,不多说了)。

本文从问题定位之后开始讲:

image.png

前言

小明写了一个自定义排序的代码,简化后如下。聪明的你快来帮小明review一下吧。

代码

背景:有一批休息室,status是状态,其中1表示空闲,8表示使用中,2表示在维修。需要按照1空闲<8使用中<2在维修的顺序进行排序。

例如:输入:[1,8, 2, 2, 8, 1, 8],期望输出:[1, 1, 8, 8, 8, 2, 2]。list不为空,数量小于100。

环境:JDK 8

小明的代码如下:

/**
* 排序
*/
private static int compare(Integer status1, Integer status2) {
        // 1<8<2 ,按照这样的规则排序
        if (status2 != null && status1 != null) {
            // 2-维修中, 维修中排到最后面
            if (status2.equals(2)) {
                return -1;
            } else {
                // 8-使用中, 排在倒数第二,仅在维修中之前
                if (status2.equals(8) && !status1.equals(2)) {
                    return -1;
                }
            }
        }
        return 0;
    }

  //Test 
  public static void main(String[] args) {
       List<Integer> list = Lists.newArrayList(1, 8, 2, 2, 8, 1, 8);
        System.out.println("排序前:"+list);
        list.sort(Test::compare);
        System.out.println("排序后:"+list);
    }




看上面的代码有问题么?别急,咱们先给个入参试一下。

测试

[ 1, 8, 2, 2, 8, 1, 8 ]

 public static void main(String[] args) {
       List<Integer> list = Lists.newArrayList(1, 8, 2, 2, 8, 1, 8);
        System.out.println("排序前:"+list);
        list.sort(Test::compare);
        System.out.println("排序后:"+list);
    }




输出:

排序前:[1, 8, 2, 2, 8, 1, 8]
排序后:[1, 1, 8, 8, 8, 2, 2]




结论:结果是对的,符合预期 。 ( 按照1空闲<8使用中<2维修中的顺序进行排序) 。


嗯,看起来排序是对的。但确实是有问题呢?

(小明OS :哪里有问题?不可能有问题!我本地是好的!)

image.png

那我们看看情景复现

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

源码解析Collections.sort ——从一个逃过单测的 bug 说起 的相关文章

  • 一组内所有对的组合

    我想计算你可以组成一个集合的所有可能的对列表 例如 input 1 2 3 4 5 6 output 1 2 3 4 5 6 2 3 4 5 1 6 2 4 1 3 5 6 注意 这个例子只是输出中的一些随机内容 大部分都被删除了 我不关心
  • Java 7 中是否有针对 ImmutableEnumSet 的计划?

    我希望拥有 EnumSet 的所有效率并传递它 而不用担心有人会修改它 您可以使用 Google 集合 Guava 获得不可变的 EnumSet 资源 番石榴主页 http code google com p guava libraries
  • 流星合并同一集合的光标

    在我的社交应用程序 如 FB 中 我有一个奇怪的需要 将同一集合用户的两个光标合并到一个发布中 Meteor 服务器打印此错误 发布函数为集合用户返回了多个游标 也许这在 Meteor 0 7 2 中无法完成 也许我的方法是错误的 但我发现
  • Trie 节省了空间,但是如何节省空间呢?

    我对 Trie 实现如何节省空间并以最紧凑的形式存储数据感到困惑 如果你看下面的树 当您在任何节点存储字符时 您还需要存储对该字符的引用 因此对于字符串的每个字符 您需要存储其引用 好吧 当常见字符到达时 我们节省了一些空间 但在存储对该字
  • 以 ng-repeat 角度随机播放数组

    我正在创建一个测验 每次开始测验时我都想打乱问题的顺序 这样它们就不会每次都以相同的顺序出现 我的 html 代码中有这样的内容 div div question question div img img class quizImg div
  • 按某些字段排序的迭代学说集合

    我需要这样的东西 products Products getTable gt find 274 foreach products gt Categories gt orderBy title as category echo categor
  • 在java中迭代集合时从集合中删除项目

    我希望能够在迭代集合时从集合中删除多个元素 最初 我希望迭代器足够聪明 能够让下面的简单解决方案发挥作用 Set
  • C# Collection 的最大容量在哪里定义?

    我尝试向一个Collection添加大量元素 每个元素都是简单的数据传输对象 具有基本数据类型的五个属性 没有什么特别的 在循环中添加新条目时 我总是收到 OutOfMemoryException 有趣的是 当我尝试添加第 8388608
  • 列表有简短的 contains 函数吗?

    给定一个列表xs和一个值item 如何检查是否xs包含item 即 如果任何元素xs等于item 有没有类似的东西xs contains item For performance considerations see Fastest way
  • 在 Ruby on Rails 中渲染部分集合正在乘以项目

    我想在 Ruby on Rails 的页面中显示项目列表 我使用部分 in my index html erb我有的文件 in list news html erb I have div class news div
  • List、IList、IEnumerable、IQueryable、ICollection,哪个返回类型最灵活?

    我之前已经在这里看到过这个问题 但我不满意我理解的完整后果 问题是使用 linq to sql 返回的数据层应该使用什么返回类型以获得最大的灵活性和查询能力 这是我读过 发现的 IEnumerable 是有限的 只允许向前读操作 IEnum
  • 在流星收集加载时显示加载程序

    我有一个模板 task list 看起来像这样 each tasks gt task each Template task list tasks返回一个集合 在用户界面中 加载似乎需要一些时间 当集合正在加载时 我想显示一个加载指示器 关于
  • 按排序顺序存储条目并检索条目周围的条目

    我正在尝试模拟一个游戏板 多个玩家可以提交他们的游戏分数 POJO 即 Entry java 代表排行榜中的一个条目 注意重写的 equals 方法 位置是在排行榜中的位置 1 是拥有 最高分 public class EntryTreeM
  • 是否可以使用 Java Guava 将函数应用于集合?

    我想使用 Guava 将函数应用于集合 地图等 基本上 我需要调整 a 的行和列的大小Table分别使所有行和列的大小相同 执行如下操作 Table
  • 限制实体框架中子实体的数量

    底线在前 有没有一种简洁的方法可以限制可以属于实体框架中父级的子实体的数量 我现在使用的是4 3 1 问题 我正在开发一个 ASP NET MVC3 站点 它通过使用实体框架的数据访问层访问数据 我有一个 SearchList 实体 它与搜
  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 在泛型方法中返回原始集合类型

    假设我们想要创建一个像这样的函数minBy返回集合中同等极简主义的所有元素 def multiMinBy A B Ordering xs Traversable A f A gt B val minVal f xs minBy f xs f
  • 哪个集合更适合存储多维数组中的数据?

    我有一个multi dimensional array of string 我愿意将其转换为某种集合类型 以便我可以根据自己的意愿添加 删除和插入元素 在数组中 我无法删除特定位置的元素 我需要这样的集合 我可以在其中删除特定位置的数据 也
  • [重复]

    这个问题在这里已经有答案了 有什么区别List
  • Scala:var List 与 val MutableList

    在 Odersky 等人的 Scala 书中 他们说使用列表 我还没有从头到尾读过这本书 但所有的例子似乎都使用了 val List 据我了解 还鼓励人们使用 vals 而不是 vars 但在大多数应用程序中 使用 var List 或 v

随机推荐

  • Python小项目:利用tkinter开发AI对战井字棋游戏

    文章目录 1 前言 2 代码分模块介绍 2 1 导入需要的库 2 2 定义全局变量 2 2 定义玩家类 2 3 定义页面类 2 4 定义页面变化类以及玩家与AI轮流转换下子权限 2 5 定义判断胜负类 2 6 定义智能AI下子类 3 整体代
  • java util.function.Supplier

    Interface Supplier
  • Java-模板方法设计模式

    Java 模板方法设计模式 1 概念 2 code举例 package p2 public class TemplateTest public static void main String args Template t new SubT
  • Web API-BOM- 操作浏览器

    Window对象 BOM Browser Object Model 是浏览器对象模型 window 对象下包含了 navigator location document history screen 5个属性 即所谓的 BOM 浏览器对象
  • h5手机端及pc端标准文档结构

    pc端
  • 为什么阻抗等于实加虚部呢?为什么有虚部呢,虚部是什么啊?

    为什么阻抗等于实加虚部呢 为什么有虚部呢 虚部是什么啊 2012 09 25 17 16 江山八秀 分类 物理学 浏览372次 提问者采纳 2012 09 25 17 40 电阻用实部表示 电抗用正的虚部表示 电容用负的虚部表示 一个器件的
  • 系列一、Fate简介及基于Docker的单机部署

    一 Fate简介 Fate是一个工业级联邦学习框架 所谓联邦学习指的就是可以联合多方的数据 共同构建一个模型 与传统数据使用方式相比 它不需要聚合各方数据搭建 数据仓库 联邦学习在联合计算建模的过程中 多方机构之间的数据是不会进行共享的 实
  • C++ ofstream和ifstrem

    原文出自 比特网 转载请保留原文链接 http soft chinabyte com database 460 11433960 sh ofstream是从内存到硬盘 ifstream是从硬盘到内存 其实所谓的流缓冲就是内存空间 在C 中
  • 【问题解决】ElasticSearch分页查询时数据顺序错乱/不一致的问题

    问题解决 ElasticSearch分页查询时数据顺序错乱 不一致的问题 问题描述 使用ElasticSearch分页查询时 每次输入同样的分页参数以及查询条件 得到的结果不一致的问题 问题分析 ElasticSearch中索引可能是由多个
  • mysql in 的两种用法

    简述MySQL 的in 的两种用法 他们分别是在 in 关键字后跟一张表 记录集 以及在in后面加上字符串集 先讲后面跟着一张表的 首先阐述三张表的结构 s sno sname sex age dept 学生信息表 c cno cname
  • 并发编程 三 synchronized

    多线程编程中 有可能会出现多个线程同时访问同一个共享 可变资源的情况 这个资源我们称之其为临界资源 这种资源可能是 对象 变量 文件等 由于线程执行的过程是不可控的 所以需要采用同步机制来协同对对象可变状态的访问 实际上 所有的并发模式在解
  • 双线性插值(超级易懂的)

    双线性插值 简介 在两个方向分别进行一次线性插值 首先在一个方向上使用线性插值 然后再在另一个方向上使用线性插值执行双线性插值 尽管每个步骤在采样值和位置上都是线性的 但是插值总体上不是线性的 而是在采样位置上是二次的 作用 一般用于重新采
  • 手把手带你用PyQt5做小型桌面应用

    导语 想制作属于自己的桌面应用程序吗 今天Disen带你手把手入门 桌面应用 什么是桌面应用 即在操作系统的可视化的桌面上 可以运行的程序 比如说QQ 微信 爱奇艺等这些都是桌面应用 早期开发桌面应用 都用哪些语言呢 桌面应用软件 在操作系
  • SpringMVC + ajaxfileupload的多文件上传

    最近做一个springmvc ajax多文件上传 倒腾了下 查阅了部分资料搞定了 现在分享 1 Spring mvc a xml配置
  • 线性代数的本质(Essense Of Linear Algebra)[1]

    论文转载自https blog csdn net wenzhunpu article details 77871631 最近学习了B站上一个关于线性代数的视频Essense Of Linear Algebra 主要从几何方面去讲解 非常形象
  • Hbase集成到Hadoop的一些注意事项

    安装 部署hadoop和hbase的文章网上已经很多了 这里说下自己安装 部署时遇到的 一些问题 1 hadoop env sh的文件里添加 export HADOOP CLASSPATH HBASE HOME hbase 0 20 3 j
  • 华硕主板怎么进入bios

    bios是电脑的基本输入输出系统 有一些电脑系统设置等需要在bios系统内完成 比如说cpu电压 温度等参数设置 磁盘模式修改 硬盘启动项顺序修改等等都是需要bios内完成 有使用华硕电脑的用户不知道华硕主板怎么进入bios 下面小编就教下
  • 联合Java攻城狮社区,推出Java技能树有奖征文活动,期待你的加入

    目录 一 立志存高远 笃行践初心 二 如何学习Java 三 哪吒造Java技能树 1 CSDN官方技能树 2 哪吒造山寨版Java技能树 3 技能树评委 4 通过打榜赢取精美礼物 5 如何参与Java技能树征文活动呢 四 社区版每日一题活动
  • 用户忠诚度:小程序积分商城的用户保持方法

    随着移动互联网的蓬勃发展 小程序积分商城已经成为了许多企业私域营销的热门选择 这个商城不仅可以吸引用户参与 还可以提高用户的忠诚度 进一步加深用户与品牌的互动关系 然而 要实现用户的忠诚度 需要一系列的策略和方法 本文将深入探讨如何通过小程
  • 源码解析Collections.sort ——从一个逃过单测的 bug 说起

    本文从一个小明写的bug 开始 讲bug的发现 排查定位 并由此展开对涉及的算法进行图解分析和源码分析 事情挺曲折的 因为小明的代码是有单测的 让小明更加笃定自己写的没问题 所以在排查的时候 也经历了前世的500年 去排查排序后的list改