List.sort()方法使用拉姆达表达式进行排序的一个例子

article/2025/11/11 11:05:36

这是牛客网华为java题库的一道题:HJ26 字符串排序
题中要求,对字符串中的英文字母不分大小写按照字典顺序排序,遇到相同的字母,要求保持它们的相对顺序不变,非英文字母字符保持原位置不变。例如:
输入:A Famous Saying: Much Ado About Nothing (2012/8).
输出:A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
题解当中有这样一段代码:

List<Character> list=new ArrayList<Character>();for(Character ch:str.toCharArray()){if(isLetter(ch))list.add(ch);}//list中的元素为:[A, F, a, m, o, u, s, S, a, y, i, n, g, M, u, c, h, A, d, o, A, b, o, u, t, N, o, t, h, i, n, g]
list.sort((a,b)->Character.toLowerCase(a)-Character.toLowerCase(b));

(a,b)->Character.toLowerCase(a)-Character.toLowerCase(b)是一个拉姆达表达式,表示输入a,b两个值,返回a,b转化为小写字母的差值:Character.toLowerCase(a)-Character.toLowerCase(b)
查阅资料发现拉姆达表达式在sort方法中的应用情况是这样的:

list.sort( (a,b)->a-b) a-b>0 donothing
list.sort( (a,b)->a-b) a-b>0 donothing
list.sort( (a,b)->a-b) a-b<0 交换a和b的位置

为弄清楚该语句实际运行时a,b的值,对该程序进行debug,发现a,b的值并非我认为的a在b之前,而是b在a之前:在这里插入图片描述
显然,Character.toLowerCase(a)-Character.toLowerCase(b)=‘F’-‘A’=70-65=5>0,于是A和F不交换位置。
跟踪(a,b)的变化,发现:

A, F, a, m, o, u, s, S, a, y, i, n, g, M, u, c, h, A, d, o, A, b, o, u, t, N, o, t, h, i, n, g
(F,A),(a,F),(a,A),(m,a),(m,F),(o,f),(o,m),(u,f)...(a,o),(a,F),(a,a)...

分析:
(F,A),a-b>0,不交换
(a,F),a-b<0,交换,F已经是是i-1序列最小值,交换之后list变为A, a, F, m, o, u, s,S,a,y,i,n,g…
(a,A),a-b=0,不交换
(m,a),a-b>0,不交换
(m,F),a-b>0,不交换
(o,f),a-b>0,不交换
(o,m),a-b>0,不交换
(u,f),a-b>0,不交换

(a,o),a-b<0,不交换,继续找更小的值
(a,F),a-b,不交换,继续找更小的值
(a,a),a-b=0,不交换,继续找更大的值,发现只有F,交换a和F,list变为A, a, a, m, o, s, S,u,F,y,i,n,g…

看起来和二分法十分相像:
设list的索引i(i从0开始),设high=i,low=0;
比较元素i的值和元素mid=(high+low)/2(向下取整)的值
若前者小于等于后者,则令high=(high+low)/2,继续比较元素i和j的值,若前者大于后者,则令low=(high+low)/2,继续比较元素i和元素mid的值,直到在i-1序列中找到首次大于i的值mid(保证low和high差值大于1,否则结束),交换i和mid的值。(每次将i和它左边的元素进行比较时,i左边的序列一定是不严格递增序列,每次遍历都会得到一个不严格递增序列)
查看源码,发现ArrayList的sort方法的确是用二分法实现的。

    private static <T> void binarySort(T[] a, int lo, int hi, int start,Comparator<? super T> c) {assert lo <= start && start <= hi;if (start == lo)start++;for ( ; start < hi; start++) {T pivot = a[start];// Set left (and right) to the index where a[start] (pivot) belongsint left = lo;int right = start;assert left <= right;/** Invariants:*   pivot >= all in [lo, left).*   pivot <  all in [right, start).*/while (left < right) {int mid = (left + right) >>> 1;if (c.compare(pivot, a[mid]) < 0)right = mid;elseleft = mid + 1;}assert left == right;/** The invariants still hold: pivot >= all in [lo, left) and* pivot < all in [left, start), so pivot belongs at left.  Note* that if there are elements equal to pivot, left points to the* first slot after them -- that's why this sort is stable.* Slide elements over to make room for pivot.*/int n = start - left;  // The number of elements to move// Switch is just an optimization for arraycopy in default caseswitch (n) {case 2:  a[left + 2] = a[left + 1];case 1:  a[left + 1] = a[left];break;default: System.arraycopy(a, left, a, left + 1, n);}a[left] = pivot;}}

http://chatgpt.dhexx.cn/article/Wpip0Ak4.shtml

相关文章

拉姆达表达式

1、Queryable 用于拉姆达表达式操作 //---------Queryable<T>,扩展函数查询---------// //---------Queryable<T>,扩展函数查询---------////针对单表或者视图查询//查询所有 var student db.Queryable<Student>().ToList(); var studentDynamic db.Querya…

java 拉姆达表达式_Java8中foreach与拉姆达表达式的组合使用

1. forEach and Map 1.1 通常这样遍历一个Map Map items = new HashMap<>(); items.put("A", 10); items.put("B", 20); items.put("C", 30); items.put("D", 40); items.put("E", 50); items.put("F", 60)…

Matlab系列之数组(矩阵)的生成

从本篇开始&#xff0c;会有一段时间都将用于记录数组、矩阵的操作等等&#xff0c;如果以前没有接触过相关的&#xff0c;可能会觉得要展示的是很复杂的东西&#xff0c;但并不是&#xff0c;这是一个很简单的部分&#xff0c;但也是一个很重要的部分&#xff0c;至少现在的我…

MATLAB-数组的使用

数组的使用&#xff08;持续更新&#xff09; randperm--数组随机排列permute--置换数组维度cat--串联数组squeeze--删除数组中长度为1的维度reshape--重构数组repmat--重复数组副本数组中的&#xff1a;sort-数组的排序dig-创建对角矩阵eig--特征值和特征向量magic--幻方矩阵m…

matlab定义数组和相关函数

matlab作为一个大型的计算软件&#xff0c;里面有许多对数组的操作&#xff0c;所以数组的定义和数组的操作是一个必不可少的部分。 1 数组的定义 在matlab中对数组的定义较为灵活&#xff0c;因为特殊矩阵较多&#xff0c;所以有许多特定的定义方法。比较常见的有三种&#…

Matlab的数组索引

在 MATLAB中&#xff0c;根据元素在数组中的位置&#xff08;索引&#xff09;访问数组元素的方法主要有三种&#xff1a;按位置索引、线性索引和逻辑索引。 按元素位置进行索引 最常见的方法是显式指定元素的索引。例如&#xff0c;要访问矩阵中的某个元素&#xff0c;请依序…

Matlab笔记-数组

一、结构数组的基本使用 结构体的定义即为C语言中结构体的初始化&#xff0c;其引用成员&#xff08;在Matlab中为field,字段的意思&#xff09;和C语言相同。 1、直接赋值 >> student(1).nameSilen; student(1).id1234; student(1).grade[1 2 3;4 5 6;7 8 9]; stude…

matlab三维数组

三维数组的定义&#xff1a;在MATLAB中&#xff0c;习惯性的将二维数组的第一维称为“行”&#xff0c;第二维称为“列”&#xff0c;而于三维数组&#xff0c;其第三维习惯性地称为“页”。 定义一个三维数组&#xff1a; A&#xff08;2&#xff0c;2&#xff0c;2&#xf…

MATLAB基础——关于数组(一)

变量和数组 MATLAB程序的基本数据单元是数组&#xff0c;标量在MATLAB中也被当做数组来处理 数组可以定义为向量&#xff08;一般描述为一维数组&#xff09;或矩阵&#xff08;一般描述为二维或多维&#xff09; 访问数组中的元素&#xff1a;数组名&#xff08;&#xff09;…

Matlab 数组与矩阵

矩阵 1、v21:3:18 ;表示的是从1 开始 18 结束&#xff0c;间隔为3 的一个等差数列v2 1 4 7 10 13 162、linspace(1,10,9);,介于1-10 之间&#xff0c;取9个数&#xff0c;使得他们是一个等差数列 >> linspace(1,10,9)ans 1.0000 2.1250 3.250…

matlab常用的数组操作总结

总结一下需要的matlab数组操作&#xff0c;免得每次都要去官网上找 参考文献&#xff1a;多维数组 - MATLAB & Simulink - MathWorks 中国: https://ww2.mathworks.cn/help/matlab/math/multidimensional-arrays.html#f1-87418 文章目录 1创建并扩展多维普通数组1普通数组引…

MATLAB怎么创建矩阵和数组

参考 MATLAB怎么创建矩阵和数组 - 云社区 - 腾讯云 第一步&#xff1a;首先教给大家如何创建数组&#xff0c;MATLAB创建数组的方法比较简单&#xff0c;我们在MATLAB中输入如下代码&#xff1a;x[2 4 6 8 10] 即可创建数组&#xff0c;数据之间使用空格或者逗号隔开&#xff…

MATLAB 数组计算

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

MATLAB-数组

数组 数组分类按照数组元素个数与排列方式分类按照数组的存储方式分类 创建数组直接输入函数生成 数组操作获取数组中的元素矩阵元素的引用单个元素的引用多个元素的引用&#xff1a;冒号的特殊用法 各类型数组操作数组的算术操作数组的逻辑运算使用库函数数组连接数组切片数组…

MATLAB中的数组

一、什么是数组 数组是组织成行和列的数据值的组合。 数组可以分为向量和矩阵。 向量通常用来描述只有一维的数组&#xff1b;而矩阵用来描述二维或者多维的数组。 数组在内存中存储是按列存储的。 二、创建和初始化一维或二维数组 1、在赋值语句中初始化 % array1为一维数…

MATLAB学习笔记——数组

MATLAB的数组 数组 数组的创建 &#xff08;1&#xff09;直接输入法 1、建立数组最直接的方法是在命令窗口直接输入数组 2、数组元素间用空格&#xff0c;逗号或分号分隔。 3、空格和逗号分隔建立行向量&#xff0c;元素之间用分号分隔建立列向量。 调用格式&#xff1…

Matlab中的向量和数组(超详细)

Matlab中的向量和数组&#xff08;超详细&#xff09; 文章目录 Matlab中的向量和数组&#xff08;超详细&#xff09;Matlab中的向量介绍创建向量向量的大小索引向量数值索引逻辑索引 缩短向量向量运算算术运算逻辑运算sum()、min()、max()、round()、ceil()、floor()、fix()切…

Windows server :DHCP服务 地址保留DHCP域备份

实验环境&#xff1a;在虚拟机上 一台Windows server 2016 一台Windows 10 1.DHCP 地址保留 我们到server上的服务器管理界面 右上角工具》dhcp 进入dhcp 依次找到作用域 然后我们去看被Windows 10 保留分配的mac地址 可以看到物理地址为&#xff1a;00-0C-29-77-BF-7C 这时再…

计算机ip保留地址,分类ip地址中,保留地址有哪些?具体点说说,作业。

分类ip地址中,保留地址有哪些?具体点说说,作业。以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 分类ip地址中,保留地址有哪些?具体点说说,作业。 A类地址中的私有地址和保留地址: ①10.0.0.1到10.255.25…

保留的IP地址

主机ID全为0的地址&#xff1a;特指某个网段&#xff0c;比如192.168.10.0 255.255.255.0。指192.168.10.0网段。主机ID全为1的地址&#xff1a;特指该网段的全部主机&#xff0c;如果你的计算机发送数据包使用主机ID全是1的IP地址&#xff0c;用作广播&#xff0c;数据链路层…