java同时边写边读文件_Java边用边学: 我有5种方法写排序

需求及代码分析

下面的一段简单的排序代码(按照员工的年龄的倒序排列),可以有大概这么5种写法:

final List employees = ...;

// 1.匿名类

employees.sort(new Comparator() {

@Override

public int compare(Employee e1, Employee e2) {

return Integer.compare(e1.getAge(), e2.getAge());

}

}.reversed());

// 2.Lambda

// e2在前,倒序

employees.sort(

(e1, e2) -> Integer.compare(e2.getAge(), e1.getAge())

);

// 3.Named Lambda

final Comparator comparator =

(e1, e2) -> Integer.compare(e1.getAge(), e2.getAge());

employees.sort(comparator.reversed());

// 4.复用 + Lambda

employees.sort(

comparingInt((Employee e) -> e.getAge()).reversed()

);

// 5.复用 + 方法引用

employees.sort(

comparingInt(Employee::getAge).reversed()

);

没什么好说的,Java 8之前的经典写法了。(至于是不是需要调用reversed()还是直接把e2放在e1前面,这个后面有答案)

Java 8+的Lambda,由于需要实现倒序,所以程序猿很注意的把e2写在了e1前面了(并配有完美的注释)

命名的Lambda

由于Lambda是没有名字的,所以想给它来个倒序,不得不给它先取个名字,然后就可以直接调用reversed()来声明我这个是倒序啊!

复用 + Lambda

Java自带的类库其实已经很丰富了,所以直接拿来用吧:Comparator.comparingInt(ToIntFunction)完美符合当前需求,用一段Lambda实现了ToIntFunction。

复用 + 方法引用

同上,用方法引用替换了Lambda。

讨论/争论开始

很容易写错的排序

这个排序看上去简单,但其实写错也很容易,大概的错误点包括:

都写成e1或e2:

Integer.compare(e1.getAge(), e1.getAge());

比较的属性不一致:

Integer.compare(e1.getAge(), e2.getLevel());

e1和e2的前后位置(涉及到倒序还是顺序)

我们的实现3.Named Lambda的排序其实写反了。它的Lambda是倒序(没错啊,我们的业务是需要倒序),问题是它在使用的时候再次反序了下,那就又回到顺序了。

都写成e1/e2

比较的属性不一致

e1和e2的前后位置

#1.匿名类

中招

中招

中招

#2.Lambda

中招

中招

中招

#3.命名的Lambda

中招

中招

中招

#4.复用+Lambda

#5.复用+方法引用

实现#4和#5就很聪明,直接用Java的类库,正确性完全有保证(e1和e2的谁前谁后无需关心)。对于倒序则简单的调用下reversed(),完事!另外#5的方法引用让可读性更进一步。

亲民的函数式编程

从左到右读完这句

employees.sort(

comparingInt(Employee::getAge).reversed()

);

大概可以获得下列信息:

对列表进行排序需要:

按照员工的年龄排序

且是倒序

就这么读过,代码的自说明能力完整的表述了其功能。

然后我们对比下#2.Lambda:

employees.sort(

(e1, e2) -> Integer.compare(e2.getAge(), e1.getAge())

);

其解读大概是这样的:

对列表进行排序需要:

嗯,e1和e2应该是前后相邻的两个Employee实例

都取出了年龄来比较

e2在前,应该是倒序吧(Code Review的同学比较严谨,查了下Javadoc)。嗯,倒序!

如果需求再复杂点,那我们第5种的优势会更明显。

譬如先按年龄的倒序排列,如果年龄相同,则按性别的顺序排列:

employees.sort(

comparingInt(Employee::getAge).reversed() // 年龄(倒序)

.thenComparing(Employee::getGender) // 第二序列是性别(顺序)

);

换成其他几种写法,估计很难一眼看懂了。

结论

方法引用优先于Lambda

有用的Java类库,譬如Comparator, Collectors

希望这篇博文能对你有所帮助,喜欢的话点个赞吧!

f0ccfa1909c2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值