在Java 8之前,我们实现了Comparable.compareTo(...)
,如下所示:
public int compare(Person a, Person b) {
return new CompareToBuilder()
.append(a.getLastName(), b.getLastName())
.append(a.getFirstName(), b.getFirstName())
.toComparison();
}
从Java 8开始,我们可以这样做:
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
新的Java 8方式可能允许我们删除commons-lang3
依赖项。 新的Java 8更快吗?有没有办法自动迁移?我没有找到IntelliJ的意图。
请注意,当存在逆序并且涉及非自然比较时,它会变得有点复杂:
public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) {
return new CompareToBuilder()
.append(b.hasAnyFailure(), a.hasAnyFailure()) // Reverse
.append(a.getAverageScore(), b.getAverageScore(), resilientScoreComparator)
.toComparison();
}
变为
public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) {
return Comparator
.comparing(SingleBenchmarkResult::hasAnyFailure, Comparator.reverseOrder()) // Reverse
.thenComparing(SingleBenchmarkResult::getAverageScore, resilientScoreComparator)
.compare(a, b);
}
答案 0 :(得分:8)
如果你这样写的话
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
您通过为每次比较构建新的Comparator
来浪费性能。在查看周围的代码时,它显然是荒谬的。 compare(Person a, Person b)
方法肯定是实现Comparator<Person>
的类的一部分,您可以在某个地方实例化以获得所需的比较器。您应该用唯一的Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName)
实例替换那个实例,并在整个操作过程中使用。
E.g。
// reusable
static final Comparator<Person> By_NAME = Comparator
.comparing(Person::getLastName).thenComparing(Person::getFirstName);
或临时
listOfPersons.sort(Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));
如果你这样使用它,它很可能会更快。但是,您应该看到,没有简单的基于模式的替换可能。您必须使用该简单声明性构造替换该类的使用站点,并决定是将多个使用站点使用共享比较器实例还是ad-hoc创建它。然后,您可以删除整个旧的实现类,或者至少从它中删除比较器功能,如果它仍然用于其他目的。
答案 1 :(得分:2)
我认为没有任何预先定义的检查。您可能会尝试使用IntelliJ的structural-search,尽管我认为对于每种可能的情况都可能非常棘手。对于具有两个比较的简单情况的一种可能性可能如下:
搜索模板(出现次数$TYPE$
和$z$
为2):
$ReturnType$ $MethodName$($TYPE$ $z$) {
return new CompareToBuilder()
.append($A$.$m$(), $B$.$m$())
.append($A$.$m1$(), $B$.$m1$())
.toComparison();
}
替换模板:
$ReturnType$ $MethodName$($TYPE$ $z$) {
return java.util.Comparator
.comparing($TYPE$::$m$)
.thenComparing($TYPE$::$m1$)
.compare($A$, $B$);
}
我不是结构搜索的专家,但我想你必须为或多或少比较的电话制作另一种模式。