【发布时间】:2018-06-15 01:45:06
【问题描述】:
集合排序没有给我预期的结果,还是我误读了方法?
要排序的 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}]
【问题讨论】:
-
你的比较器也应该考虑
id。 -
如果
compare(o1, o2)返回1,则表示o1更大。第一次调用的结果完全符合。 -
你的第一个 if 语句应该是
if (o1.isLine() == o2.isLine())- 否则,如果两者都是真的,你的排序有时会返回 1,有时会返回 -1(当它应该一直返回 0 时)。但实际上您可以将整个方法替换为!Boolean.compare(o1.isLine(), o2.isLine())。 -
@CrazySabbath 如果您觉得对未来的访问者有帮助,欢迎您自己在答案中发布我的 cmets。
-
排序是从低到高。