Geo*_*met 8 intellij-idea comparator java-8 apache-commons-lang apache-commons-lang3
在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();
}
Run Code Online (Sandbox Code Playgroud)
从Java 8开始,我们可以这样做:
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
Run Code Online (Sandbox Code Playgroud)
新的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();
}
Run Code Online (Sandbox Code Playgroud)
变
public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) {
return Comparator
.comparing(SingleBenchmarkResult::hasAnyFailure, Comparator.reverseOrder()) // Reverse
.thenComparing(SingleBenchmarkResult::getAverageScore, resilientScoreComparator)
.compare(a, b);
}
Run Code Online (Sandbox Code Playgroud)
如果你这样写的话
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
Run Code Online (Sandbox Code Playgroud)
你是通过Comparator为每个比较构建一个新的来浪费性能.在查看周围的代码时,它显然是荒谬的.该compare(Person a, Person b)方法肯定是类实现的一部分Comparator<Person>,您可以在某个地方实例化以获得所需的比较器.您应该用唯一的实例替换该实例Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName),在整个操作中使用.
例如
// reusable
static final Comparator<Person> By_NAME = Comparator
.comparing(Person::getLastName).thenComparing(Person::getFirstName);
Run Code Online (Sandbox Code Playgroud)
或临时的
listOfPersons.sort(Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));
Run Code Online (Sandbox Code Playgroud)
如果你这样使用它,它很可能会更快.但是,您应该看到,没有简单的基于模式的替换可能.您必须使用该简单声明性构造替换该类的使用站点,并决定是将多个使用站点使用共享比较器实例还是ad-hoc创建它.然后,您可以删除整个旧的实现类,或者至少从它中删除比较器功能,如果它仍然用于其他目的.
我认为没有任何预先定义的检查。您可能会尝试使用 IntelliJ 的结构搜索,尽管我认为针对每种可能的情况执行此操作可能相当棘手。具有两次比较的简单情况的一种可能性可能如下:
$TYPE$搜索模板(和的出现次数$z$为2):
$ReturnType$ $MethodName$($TYPE$ $z$) {
return new CompareToBuilder()
.append($A$.$m$(), $B$.$m$())
.append($A$.$m1$(), $B$.$m1$())
.toComparison();
}
Run Code Online (Sandbox Code Playgroud)
替换模板:
$ReturnType$ $MethodName$($TYPE$ $z$) {
return java.util.Comparator
.comparing($TYPE$::$m$)
.thenComparing($TYPE$::$m1$)
.compare($A$, $B$);
}
Run Code Online (Sandbox Code Playgroud)
我不是结构搜索方面的专家,但我想您必须为具有或多或少比较的调用制定另一种模式。
| 归档时间: |
|
| 查看次数: |
1939 次 |
| 最近记录: |