收藏品排序不是给我我期待的结果,还是我误读了这个方法?
要对Row对象列表进行排序:
public class Row {
private int id;
private boolean line;
public Row(int id, boolean line) {
this.id = id;
this.line = line;
}
public boolean isLine() {
return line;
}
@Override public String toString() {
return "Row{" + "id=" + id + ", line=" + line + '}';
}
}
开始数据:
[Row{id=0, line=true}, Row{id=1, line=false}, Row{id=2, line=true}, Row{id=3, line=false}]
排序代码:
Collections.sort(rows, new Comparator<Row>(){
@Override public int compare(Row o1, Row o2) {
if (!o1.isLine() && !o2.isLine()) return 0;
if (o1.isLine()) {
return 1;
} else {
return -1;
}
}
});
结果:
[Row{id=1, line=false}, Row{id=3, line=false}, Row{id=0, line=true}, Row{id=2, line=true}]
我受到了压迫,line=true
的所有对象都应该在列表的开头,而不是结尾。
如果我略微更改Comporator实现:
Collections.sort(rows, new Comparator<Row>(){
@Override public int compare(Row o1, Row o2) {
if (!o1.isLine() && !o2.isLine()) return 0;
if (o1.isLine()) {
return -1;
} else {
return 1;
}
}
});
结果:
[Row{id=2, line=true}, Row{id=0, line=true}, Row{id=1, line=false}, Row{id=3, line=false}]
现在可以在列表的开头找到line=true
的所有对象,但它们已切换位置(id=0
应该是第一个)。
预期的排序结果:
[Row{id=0, line=true}, Row{id=2, line=true}, Row{id=1, line=false}, Row{id=3, line=false}]
答案 0 :(得分:3)
我受到了冲突,所有具有line = true的对象都应该在 列表的开头,而不是结束。
不像这段代码:
if (o1.isLine()) {
return 1;
}
表示o1
优于o2
因此,isLine=true
的对象将在默认顺序升序时结束。
可以在列表的开头找到所有具有line = true的对象 现在,但他们已经换了位置(id = 0应该是第一个)。
你从不在比较器实现中使用id
它永远不会被考虑。
获得:
[Row {id = 0,line = true},Row {id = 2,line = true},Row {id = 1,line = false}, 行{id = 3,line = false}]
您应该在Row
中添加一个getter来检索id
。
然后,您应该先按line=true
和id
ASC排序。
Collections.sort(rows, new Comparator<Row>(){
@Override public int compare(Row o1, Row o2) {
if (!o1.isLine() && !o2.isLine()) return 0;
if (o1.isLine() && o2.isLine()) {
return o1.getId() > o2.getId();
}
if (o1.isLine()) {
return -1;
} else {
return 1;
}
}
});
更简单的编写方法是使用Java 8 Comparator:
Comparator<Row> comparatorRow = Comparator.comparing(Row::isLine).reversed()
.thenComparing(Row::getId);
由于行已按id
排序且排序保证稳定:相等元素不会因排序而重新排序,因此您只能在{{ 1}}:
isLine
答案 1 :(得分:1)
总结@Dukeling:
Collections.sort(rows, new Comparator<Row>(){
@Override public int compare(Row o1, Row o2) {
return -Boolean.compare(o1.isLine(), o2.isLine());
}
});
这给出了预期的结果。
输入:
[Row{id=0, line=true}, Row{id=1, line=false}, Row{id=2, line=true}, Row{id=3, line=false}]
结果:
[Row{id=0, line=true}, Row{id=2, line=true}, Row{id=1, line=false}, Row{id=3, line=false}]
答案 2 :(得分:0)
你的比较不是对称的,因此被打破了。使用 Boolean 类中实现的反向比较(请注意lambda body开头的 minus ):
>sudo yum install numactl-libs.x86_64
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* elrepo: mirrors.tuna.tsinghua.edu.cn
Package numactl-libs-2.0.9-6.el7_2.x86_64 already installed and latest version
Nothing to do