我一直在研究Collections.sort和之间的区别list.sort,特别是在使用Comparator静态方法以及lambda表达式中是否需要参数类型方面。在开始之前,我知道我可以使用方法引用,例如Song::getTitle来解决我的问题,但是这里的查询并不是我想要修复的东西,而是我想要答案的东西,即Java编译器为什么以这种方式处理它。
这些是我的发现。假设我们有一个ArrayListtype Song,添加了一些歌曲,有3种标准的get方法:
ArrayList<Song> playlist1 = new ArrayList<Song>();
//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()));
一旦开始链接thenComparing,就会发生以下情况:
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到(比较)的第一个参数中:
现在是混淆部分。对于p laylist1.sort,即List,这可以解决以下两个thenComparing调用的所有编译错误。但是,对于Collections.sort,它将为第一个解决,而不是最后一个。我测试过添加了一些额外的调用thenComparing,除非我(Song p1)输入了参数,否则它总是显示最后一个错误。
与中发生的情况相同,对于TreeSet,没有编译错误,但Objects.compare最后一次调用thenComparing显示错误。
任何人都可以解释一下为什么会发生这种情况,也可以解释为什么(Song p1)在简单地调用比较方法时根本不需要使用(无需进一步thenComparing调用)。
关于同一主题的另一个查询是我对以下内容进行查询时TreeSet:
Set<Song> set = new TreeSet<Song>(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
例如,Song从用于比较方法调用的第一个lambda参数中删除类型,它显示在进行比较的调用和对的第一个调用(thenComparing但对最终调用没有)下的语法错误thenComparing-几乎与上述情况相反!然而,所有其他3个例子,即有Objects.compare,List.sort而且Collections.sort当我删除第一个Song参数类型它显示语法错误的所有电话。
提前谢谢了。
经过编辑后包含了我在Eclipse Kepler SR2中收到的错误的屏幕截图,此后我现在发现它们是特定于Eclipse的,因为在命令行上使用JDK8 java编译器进行编译时,它可以编译。
holdtom
胡说叔叔
相关分类