Java8 排序初探

Java8新增了lambda表达式以及方法引用。使得排序有了更方便的表达。以下均以字符串数组为例。


      String[] planets = new String[] { "Mercury", "Venus", "Earth", "Mars", 
            "Jupiter", "Saturn", "Uranus", "Neptune" };

一、由于String类实现了Comparable接口,使用单参数的sort方法会自动按字典序排序。

      //默认的字典序
      Arrays.sort(planets);

二、按照字符串长度排序,由于String不可变且为final,不可能重写其compareTo方法,故使用双参数形式的sort方法。

第二个参数需要一个Comparator对象,我们只需构造一个实现Comparator的类即可。

class comp implements Comparator<String>
{
	public int compare(String a,String b)
	{
		return a.length()-b.length();
	}
}
      //字符长度排序——Comparator对象
      Arrays.sort(planets,new comp());

三、第二类为最万金油的方法,但非常繁琐,你需要实现一个类,还要实现一个抽象方法。在Java8下有了函数式接口和lambda表达式,可以简化操作。

函数式接口:只有一个抽象方法的接口。

lambda表达式:一个代码块,参数,自由变量(非参数且不在该代码块中定义的变量,该变量初始化后就不会为它赋新值)

形式:(形参)-> 表达式/代码块  

如果可以推导出形参的类型,可以不写;如果只有一个参数且该参数类型可推导,小括号也可省略;

无需指定返回类型,自动推导。

Waring:如果一个lambda表达式只在某些分支返回值,而在另一分支不返回值是不合法的。

      //字符长度排序——lambda表达式
      Arrays.sort(planets, (first, second) -> first.length() - second.length());

四、方法引用

这个没有完全懂。。应该相当于c++的函数指针?反正等价于对应的lambda表达式。用  ::分隔方法名与对象或类名

      //忽视大小写字典序排序——方法引用
      Arrays.sort(planets,String::compareToIgnoreCase);

在这里 String::compareToIgnoreCase等价于 (x,y) -> x.compareToIgnoreCase(y)

方法引用主要有3中情况:

1. object::instanceMethod

2.Class::staticMethod

3.Class::instanceMethod

前两种情况下,方法引用等价于提供方法参数的lambda表达式

比如 Math::pow 等价于(x,y) -> Math.pow(x,y)

最后一种情况,带一个参数会成为方法的目标(this)

比如这里的 String::compareToIgnoreCase等价于 (x,y) -> x.compareToIgnoreCase(y)

同样的,可以在方法引用中使用this与super(效果等同于上述的第一种和第二种)

五、comparing方法

Comparing接口有一个静态的comparing方法,可以用于lambda表达式或方法引用

      //先按长度排序,再按哈希码排序————方法引用
      Arrays.sort(planets,Comparator.comparing(String::length).thenComparing(String::hashCode));

comparing有多种变体,比如thenComparing(第二排序标准,直接跟在comparing后面就行了),

comparingInt(比较int值使用,可以避免int类型装箱成Integer类再调用comparing方法)等

      //先按长度排序,再按字典序排序————lambda
      Arrays.sort(planets,Comparator.comparingInt((String p)->p.length()).thenComparing(p->p));
      System.out.println(Arrays.toString(planets));
其实还有一个使用适配器与比较器的方法,来处理某些情况下比较的key为null的情况,不过我看不懂了,以后再补


本篇红字部分来自 corejava

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值