List.sort()方法使用拉姆达表达式进行排序的一个例子
这是牛客网华为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;}}
List.sort()方法使用拉姆达表达式进行排序的一个例子相关推荐
- C# 匿名方法和拉姆达表达式
"` "`代码如下: using System; using System.Collections.Generic; using System.Linq; using System ...
- C#拉姆达(=)表达式
前言: 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(=>)表达式 介绍: "Lambda表达式"是一个匿名函数,是一种高效的类似 ...
- SqlSugar常用查询实例-拉姆达表达式
SqlSugar支持拉姆达表达式查询,匿名对象参数等,相对还是比较方便好用的. 一.查询列表: //查询列表SqlSugarClient db = SugarContext.GetInstance() ...
- 匿名函数 和 拉姆达表达式
匿名函数 匿名方法是创建与特定委托实例相关联的未命名代码块的一种方法.可以通过在代码块后面跟上delegate关键字来创建匿名方法. delegate void print();delegate st ...
- 拉姆达表达式学习(2)
本文转载自:http://www.cnblogs.com/zhouji432600/archive/2010/05/30/1747383.html 在.net3.5里面,委托的定义和实现被大大的简化了 ...
- 拉姆达表达式学习(1)
我曾经遇到一个项目,项目里面需要经常对一系列的同类型集合进行操作,如对集合进行增加元素,删除集合的指定索引的元素等等. 我们可以使用ArrayList来进行.如 1 ArrayList stringL ...
- 拉姆达表达式相关知识
拉姆达表达式 拉姆达表达式是创建匿名函数的另一种方法.因此,拉姆达表达式可以赋值给委托.虽然主要在操作LINQ中使用拉姆达表 达式,但是这种表达式也适用于委托和事件. 拉姆达表达式运算符 ...
- 一句话学会拉姆达表达式(JAVA)
LambdaExpress 一 . 理论 1.1 是什么 Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lam ...
- java1.8 Lambda拉姆达表达式深入探究
当我们遇到下面情况时: SingleObj.getInstance().setRunnable(new Runnable() {@Overridepublic void run() {} }); 编译 ...
- 拉姆达表达式 追加 条件判断 ExpressionFuncT, bool
拉姆达表达式 追加 条件判断 Expression<Func<T, bool>> 2014/11/13 14:47:59 虫虫飞520 程序员俱乐部 我要评论(0) ...
最新文章
- 完美解决方案 | 完全卸载任何版本office残余文件
- java mvc数据库 封装_Springmvc对就jdbc封装的操作
- BlockChain:区块链/加密数字货币落地技术应用高质量相关文章
- flac3d命令流实例大全_ANSYS APDL 疲劳分析实例附命令流
- 怎么修改存储路径_Power Query数据位置变了?利用参数轻松解决源文件路径问题...
- [华清远见]FPGA公益培训
- 云计算之路-阿里云上:基于Xen的IO模型进一步分析“黑色0.1秒”问题
- 遍历Map key-value的两种方法、遍历Set方法
- 符江职高计算机教什么,高县符江职高具体地址
- 基础篇5-python基本数据类型讲解1.1
- c语言接收并回现字符,C语言——字符I/O与缓冲区
- 大型网站架构演变和知识体系(转)
- Struts+Hibernate系列教材 (一)- 整合Struts和Hibernate教程
- java获取系统所有字体_java获取本机所有可用字体
- 超定方程组 matlab
- 技嘉主板前置面板没有声音的解决
- ireport java 变量_iReport —— 使用 JavaBean 作为数据源
- 泰拉瑞亚服务器config修改,泰拉瑞亚种子世界游戏配置修改教程
- 华为手机录音m4a格式怎么转换为MP3格式
- NVIDIA驱动 XORG频繁崩溃