Collections.sort 多个条件
Collections.sort for multiple conditions
我有一个要排序的对象列表。但是我有三个不同的条件。这就是为什么我有这个代码:
Collections.sort(myList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
// my code
}
});
三次。首先将条件为 x
的所有元素排序到列表底部。然后第二次将条件为 y
的所有元素排序到底部,再次对条件为 z
.
现在我想知道如何在一个比较方法中组合多个条件。所以我不必这样做三次。
编辑: 条件更清楚。我想将所有符合条件 x
的对象排序到列表底部。如果一个元素满足标准 y
,它甚至应该低于 x
,同样适用于 z
.
的模拟
您可以使用 Java 流。使用 Collection.sort()
:
时也会用到这个
myList.sort(Comparator.comparing(MyObject::getAttributeX)
.thenComparing(i -> i.getSomething().getSubValue())
.thenComparing((a, b) -> a.getInt() - b.getInt()));
如果您使用的版本低于 Java 8,您必须自己在 Comparator
中实现排序逻辑或使用外部库:
Collections.sort(myList, new Comparator<MyObject>() {
@Override
public int compare(MyObject a, MyObject b) {
int cmp0 = a.getAttributeX().compareTo(b.getAttributeX());
if (cmp0 != 0) {
return cmp0;
}
int cmp1 = a.getSomething().getSubValue().compareTo(b.getSomething().getSubValue());
if (cmp1 != 0) {
return cmp1;
}
return a.getInt() - b.getInt();
}
});
您可以使用比较链,例如:
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
看这里:link to docs
我假设 MyObject
有类似
的方法
public boolean isX() {
return // either false or true;
}
那么这样排序最简单:
Collections.sort(myList,
Comparator.comparing(MyObject::isX)
.thenComparing(MyObject::isY)
.thenComparing(MyObject::isZ));
由于 isX
等 return boolean
值,这些值被排序,false
排在 true
之前。因此,排序将确保满足 x 条件(isX
returns true)的所有对象都将出现在列表的末尾。在剩余的对象中,那些满足 y 的对象将最后移动,就在 x-s 之前。同样对于 z.
如果 x、y 和 z 是由进行排序的 class 中的方法确定的怎么办?在这个例子中我们称它为 Sorter
class。这些方法可能如下所示:
public static boolean isY(MyObject obj) {
return // either false or true;
}
您只需将 MyObject::isX
替换为 Sorter::isX
:
Collections.sort(myList,
Comparator.comparing(Sorter::isX)
.thenComparing(Sorter::isY)
.thenComparing(Sorter::isZ));
你也可以混用,在Sorter
中定义一些方法,在MyMethod
中定义一些方法。
真正发生的是 boolean
值 return 装箱到 Boolean
对象中,然后进行比较,但您不必关心这个细节。
编辑: 较低 Android API 级别的版本:
Comparator<MyObject> xyzComparator = new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
int diff = Boolean.compare(o1.isX(), o2.isX());
if (diff != 0) {
return diff;
}
diff = Boolean.compare(o1.isY(), o2.isY());
if (diff != 0) {
return diff;
}
diff = Boolean.compare(o1.isZ(), o2.isZ());
// return whether 0 or not
return diff;
}
};
Collections.sort(myList, xyzComparator);
它甚至省去了上面提到的自动装箱。
我有一个要排序的对象列表。但是我有三个不同的条件。这就是为什么我有这个代码:
Collections.sort(myList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
// my code
}
});
三次。首先将条件为 x
的所有元素排序到列表底部。然后第二次将条件为 y
的所有元素排序到底部,再次对条件为 z
.
现在我想知道如何在一个比较方法中组合多个条件。所以我不必这样做三次。
编辑: 条件更清楚。我想将所有符合条件 x
的对象排序到列表底部。如果一个元素满足标准 y
,它甚至应该低于 x
,同样适用于 z
.
您可以使用 Java 流。使用 Collection.sort()
:
myList.sort(Comparator.comparing(MyObject::getAttributeX)
.thenComparing(i -> i.getSomething().getSubValue())
.thenComparing((a, b) -> a.getInt() - b.getInt()));
如果您使用的版本低于 Java 8,您必须自己在 Comparator
中实现排序逻辑或使用外部库:
Collections.sort(myList, new Comparator<MyObject>() {
@Override
public int compare(MyObject a, MyObject b) {
int cmp0 = a.getAttributeX().compareTo(b.getAttributeX());
if (cmp0 != 0) {
return cmp0;
}
int cmp1 = a.getSomething().getSubValue().compareTo(b.getSomething().getSubValue());
if (cmp1 != 0) {
return cmp1;
}
return a.getInt() - b.getInt();
}
});
您可以使用比较链,例如:
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
看这里:link to docs
我假设 MyObject
有类似
public boolean isX() {
return // either false or true;
}
那么这样排序最简单:
Collections.sort(myList,
Comparator.comparing(MyObject::isX)
.thenComparing(MyObject::isY)
.thenComparing(MyObject::isZ));
由于 isX
等 return boolean
值,这些值被排序,false
排在 true
之前。因此,排序将确保满足 x 条件(isX
returns true)的所有对象都将出现在列表的末尾。在剩余的对象中,那些满足 y 的对象将最后移动,就在 x-s 之前。同样对于 z.
如果 x、y 和 z 是由进行排序的 class 中的方法确定的怎么办?在这个例子中我们称它为 Sorter
class。这些方法可能如下所示:
public static boolean isY(MyObject obj) {
return // either false or true;
}
您只需将 MyObject::isX
替换为 Sorter::isX
:
Collections.sort(myList,
Comparator.comparing(Sorter::isX)
.thenComparing(Sorter::isY)
.thenComparing(Sorter::isZ));
你也可以混用,在Sorter
中定义一些方法,在MyMethod
中定义一些方法。
真正发生的是 boolean
值 return 装箱到 Boolean
对象中,然后进行比较,但您不必关心这个细节。
编辑: 较低 Android API 级别的版本:
Comparator<MyObject> xyzComparator = new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
int diff = Boolean.compare(o1.isX(), o2.isX());
if (diff != 0) {
return diff;
}
diff = Boolean.compare(o1.isY(), o2.isY());
if (diff != 0) {
return diff;
}
diff = Boolean.compare(o1.isZ(), o2.isZ());
// return whether 0 or not
return diff;
}
};
Collections.sort(myList, xyzComparator);
它甚至省去了上面提到的自动装箱。