java四大特性特例举例_java8学习之比较器详解与类型推断特例

比较器详解:

这次来对比较器进行一个学习,比较器(Comparator)这个是在JDK1.2就提出的概念,只是说JAVA8针对它进行了一定的扩充,更加方便咱们使用,其中唯一的抽象方法如下:

1f1291e3d0a8984e68237560f7319790.png

而JAVA8中对这个接口进行扩展的当然就是一些默认或静态方法啦,如:

2e1bb068ddf589a852d0813ba35e1bde.png

a5203a8df655e80806eac0ab090d6c8f.png

下面来粗略的来了解一下这新增的具体实现的方法,其实大体有三大类:

349365de4d86bb9f53baebe5037aee1b.png

首先看一下reversed(),从字面意思就是对其顺序进行反序嘛:

2dbcce8d547d835753eb247081758c09.png

19439f2bd2c20d2adf9660a85d82c35a.png

有了这个辅助方法,其实如果想对其逆序排序的话,就不需要再次创建Comparator对象啦,直接调用这个方法既可,更加的方便人性。

接着再来看第二大类:comparing()相关,其中有通用的方法,也有具化的,根据使用原则,能用具化的方式就用具化的方式,因为具化的方法比通用的方法性能要优:

b5b855e071e72c8cf31d19e1c8673f77.png

最后再来看一下:thenComparing(),那这个方法主要是用来干嘛的呢?下面举个场景:

比如学生有姓名和年龄属性,对其学生集合进行比较的话,可能存在这样的一个比较规则:首先根据学生年龄进行升序排序,这时势必会有多个学生的年龄是一样的,这时可能需要对相同年龄的同学再用它的名字进行进一步排序,相当于是比较的一种串联,可以多次进行比较,这个方法就是用来解决这种场景而生的。

相当它也存在具化的方法,如下:

fc92297b08c68c929283107963ad4ede.png

接下来则用代码进行说明,目的是为了对其比较器有一个更加深刻的认识:

对如下集合进行升序排序:

cfa66709c1b96738396122465a41939d.png

可以采用默认排序规则,如下:

f944e7087f4367713da2f13d2157af53.png

接下来对其进行改造,这时按字符串的长度进行升序排序,如下:

9b904fa14a0710633b328feb605a47a6.png

继续改造,按字符串的长度的降序排序,如下:

dd1c4f51d7e9a84f25546260e486ba7a.png

接着还是按长度降序排列,这时采用方法引用,及Comparator接口提供的一些现有的方法来实现,如下:

4ff5225e1cf75cd667ee9b6a42f07914.png

编译运行:

ddabd1a438e0a9b51ecdd41209a678ca.png

很显然不符合咱们的要求:长度降序排列,这时可以调用比较器里面现成的逆序方式来实现,如下:

1ae49e60f5a089c79e3dd4a25f618a84.png

类型推断特例:

接下来咱们用Lambda表达式的方式来代替上面的方法引用来实现同样的功能,如下:

d76bd66ea98563e43a9dc5e158dee8d8.png

可以按command+左键看一上目前item是个啥类型:

948af186b6d70014e0a32c54499fb406.png

是Object类型而非String,为啥是Object类型呢?明显应该是可以类型推导成String呀,先不探究其原因,先来解决这个问题,之前在学习Lambda表达式时也提到过,对于系统无法推导出来的类型则需要显示的进行类型声明,所以可以修改代码如下:

de145be37ceac3783bc81185a2a59559.png

这算是一个类型推断的特例,那下面来找出原因为啥这种情况是无法推断的, 下面如果这么写这可以正常编译了,如下:

a03fb4285048c502c49cfcb41e99aeee.png

这是为啥呢?这是个很细的东东,可以看一下如果加了reversed()方法之后,其sort的第二个参数其实是由reversed()调用之后才返回的,也就是它相对于上下文是比较远的,因为相当于隔了两层,而如果将reversed()去掉就可正常编译的原因是因为此时sort的第二个参数是由Comparator.comparingInt()方法来返回的,而它相对于上下文是比较近的,就只有一层嘛,那为啥当加了reversed()之后将item就默认它为Object类型了呢?这时需要看一下Comparator.comparingInt()参数的定义了,看下源码:

19b54c4c9bac6b48a5d1a67548db1811.png

而对于String来说,它的父类就是Object,当系统抢断不出来元素类型是String,那肯定就把类型当成Object啦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值