这是牛客网华为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()方法使用拉姆达表达式进行排序的一个例子相关推荐

  1. C# 匿名方法和拉姆达表达式

    "` "`代码如下: using System; using System.Collections.Generic; using System.Linq; using System ...

  2. C#拉姆达(=)表达式

    前言: 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(=>)表达式 介绍: "Lambda表达式"是一个匿名函数,是一种高效的类似 ...

  3. SqlSugar常用查询实例-拉姆达表达式

    SqlSugar支持拉姆达表达式查询,匿名对象参数等,相对还是比较方便好用的. 一.查询列表: //查询列表SqlSugarClient db = SugarContext.GetInstance() ...

  4. 匿名函数 和 拉姆达表达式

    匿名函数 匿名方法是创建与特定委托实例相关联的未命名代码块的一种方法.可以通过在代码块后面跟上delegate关键字来创建匿名方法. delegate void print();delegate st ...

  5. 拉姆达表达式学习(2)

    本文转载自:http://www.cnblogs.com/zhouji432600/archive/2010/05/30/1747383.html 在.net3.5里面,委托的定义和实现被大大的简化了 ...

  6. 拉姆达表达式学习(1)

    我曾经遇到一个项目,项目里面需要经常对一系列的同类型集合进行操作,如对集合进行增加元素,删除集合的指定索引的元素等等. 我们可以使用ArrayList来进行.如 1 ArrayList stringL ...

  7. 拉姆达表达式相关知识

    拉姆达表达式 拉姆达表达式是创建匿名函数的另一种方法.因此,拉姆达表达式可以赋值给委托.虽然主要在操作LINQ中使用拉姆达表        达式,但是这种表达式也适用于委托和事件. 拉姆达表达式运算符 ...

  8. 一句话学会拉姆达表达式(JAVA)

    LambdaExpress 一 . 理论 1.1 是什么 ​ Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lam ...

  9. java1.8 Lambda拉姆达表达式深入探究

    当我们遇到下面情况时: SingleObj.getInstance().setRunnable(new Runnable() {@Overridepublic void run() {} }); 编译 ...

  10. 拉姆达表达式 追加 条件判断 ExpressionFuncT, bool

    拉姆达表达式 追加 条件判断 Expression<Func<T, bool>> 2014/11/13 14:47:59  虫虫飞520   程序员俱乐部   我要评论(0) ...

最新文章

  1. 完美解决方案 | 完全卸载任何版本office残余文件
  2. java mvc数据库 封装_Springmvc对就jdbc封装的操作
  3. BlockChain:区块链/加密数字货币落地技术应用高质量相关文章
  4. flac3d命令流实例大全_ANSYS APDL 疲劳分析实例附命令流
  5. 怎么修改存储路径_Power Query数据位置变了?利用参数轻松解决源文件路径问题...
  6. [华清远见]FPGA公益培训
  7. 云计算之路-阿里云上:基于Xen的IO模型进一步分析“黑色0.1秒”问题
  8. 遍历Map key-value的两种方法、遍历Set方法
  9. 符江职高计算机教什么,高县符江职高具体地址
  10. 基础篇5-python基本数据类型讲解1.1
  11. c语言接收并回现字符,C语言——字符I/O与缓冲区
  12. 大型网站架构演变和知识体系(转)
  13. Struts+Hibernate系列教材 (一)- 整合Struts和Hibernate教程
  14. java获取系统所有字体_java获取本机所有可用字体
  15. 超定方程组 matlab
  16. 技嘉主板前置面板没有声音的解决
  17. ireport java 变量_iReport —— 使用 JavaBean 作为数据源
  18. 泰拉瑞亚服务器config修改,泰拉瑞亚种子世界游戏配置修改教程
  19. 华为手机录音m4a格式怎么转换为MP3格式
  20. NVIDIA驱动 XORG频繁崩溃

热门文章

  1. 谷歌(gmail)邮箱开启SMTP服务
  2. html简单旋转木马
  3. 【Python05】Python转义字符
  4. 【草莓音乐节】现场美女大放送
  5. PHP四端代码,壹脉销客智能名片,全套四端开源代码
  6. Linux14.04安装Mysql Linux公社
  7. go语言加解密算法 md5 sha256
  8. Python3程序设计编程题解
  9. python怎么解压rar文件
  10. elementui el-tab添加badge,以及实时更新标记值