I am assuming that MyObject
has methods like
public boolean isX() {
return // either false or true;
}
Then sorting is easiest in this way:
Collections.sort(myList,
Comparator.comparing(MyObject::isX)
.thenComparing(MyObject::isY)
.thenComparing(MyObject::isZ));
Since isX
etc. return boolean
values, these values are sorted, false
comes before true
. So the sorting will make sure that all the objects that fulfil the x condition (isX
returns true) will come at the end of the list. Among the remaining objects, those that fulfil y will be moved last, just before the x-s. Similarly for z.
What if instead x, y and z are determined by a method in the class doing the sorting? Let’s call it the Sorter
class in this example. Such methods may look like:
public static boolean isY(MyObject obj) {
return // either false or true;
}
All you need to do is replace MyObject::isX
with Sorter::isX
:
Collections.sort(myList,
Comparator.comparing(Sorter::isX)
.thenComparing(Sorter::isY)
.thenComparing(Sorter::isZ));
You may also mix, define some methods in Sorter
and some in MyMethod
.
What really happens is that the boolean
values returned are boxed into Boolean
objects that are then compared, but you need not be concerned with this detail.
EDIT: Version for lower Android API levels:
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);
It even saves the auto-boxing mentioned above.