java 推理问题_非常困惑的Java 8 Comparator类型推理

我一直在看着Collections.sort和list.sort之间的区别,特别是关于使用Comparator静态方法以及是否在lambda表达式中需要param类型。在我们开始之前,我知道我可以使用方法引用,例如。 Song :: getTitle来克服我的问题,但是我的查询不是我想要解决的东西,而是我想要的答案,即为什么是Java编译器以这种方式处理它。

这是我的发现。假设我们有一个类型为Song的ArrayList,添加了一些歌曲,有3个标准的get方法:

ArrayList playlist1 = new ArrayList();

//add some new Song objects

playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );

playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );

playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );

这里是调用这两种类型的排序方法工作,没有问题:

Collections.sort(playlist1,

Comparator.comparing(p1 -> p1.getTitle()));

playlist1.sort(

Comparator.comparing(p1 -> p1.getTitle()));

一旦我开始链接然后比较,以下发生:

Collections.sort(playlist1,

Comparator.comparing(p1 -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

playlist1.sort(

Comparator.comparing(p1 -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

即语法错误,因为它不再知道p1的类型。所以要解决这个问题我添加了类型Song到第一个参数(比较):

Collections.sort(playlist1,

Comparator.comparing((Song p1) -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

playlist1.sort(

Comparator.comparing((Song p1) -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

现在这里有CONFUSING部分。对于playlist1.sort,即List,这解决了所有编译错误,对于以下然后比较调用。然而,对于Collections.sort,它解决它的第一个,但不是最后一个。我测试添加几个额外的调用,然后比较,它总是显示一个错误的最后一个,除非我把(歌曲p1)的参数。

现在我继续测试这个进一步创建一个TreeSet和使用Objects.compare:

int x = Objects.compare(t1, t2,

Comparator.comparing((Song p1) -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

Set set = new TreeSet(

Comparator.comparing((Song p1) -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

同样的事情发生了,对于TreeSet,没有编译错误,但对于Objects.compare最后一次调用thenComparing显示一个错误。

任何人都可以解释为什么会发生这种情况,以及为什么不需要使用(歌曲p1)在所有当简单地调用比较方法(无进一步然后比较调用)。

对同一主题的另一个查询是当我对TreeSet这样做:

Set set = new TreeSet(

Comparator.comparing(p1 -> p1.getTitle())

.thenComparing(p1 -> p1.getDuration())

.thenComparing(p1 -> p1.getArtist())

);

即从比较方法调用的第一个lambda参数中删除类型Song,它显示在比较调用下的语法错误和第一次调用thenComparing但不是最后调用thenComparing – 几乎与上面发生的情况相反!而对于所有其他3个示例,即通过Objects.compare,List.sort和Collections.sort,当我删除第一个歌曲参数类型,它显示所有调用的语法错误。

提前谢谢了。

编辑以包括我在Eclipse Kepler SR2中收到的错误的屏幕截图,我现在自从发现是Eclipse特定的,因为当编译使用JDK8 java编译器在命令行上编译确定。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值