This is my list:
Name: Ben || Age: 5 || Group: 1
Name: Andy || Age: 6 || Group: 2
Name: Charlie || Age: 6 || Group: 2
Name: Ben || Age: 5 || Group: 1
Name: Andy || Age: 5 || Group: 2
Name: Charlie || Age: 5 || Group: 1
I want to sort the list by Group
, if Group
is equal then by Age
, and if Age
is equal then by Name
. But so far I can only sort by one attribute, using Lambda Expressions:
list.sort((Object o1, Object o2) -> o1.getGroup().compareTo(o2.getGroup()));
If I try
o1.getGroup().compareTo(o2.getGroup()) && o1.getAge().compareTo(o2.getAge())
it's turned out error...
Change lambda expression to lambda {block}, and you don't have to specify the parameter types:
list.sort((o1, o2) -> {
int cmp = o1.getGroup().compareTo(o2.getGroup());
if (cmp == 0)
cmp = Integer.compare(o1.getAge(), o2.getAge());
if (cmp == 0)
cmp = o1.getName().compareTo(o2.getName());
return cmp;
});
You can use the static method Comparator.comparing
to create a comparator based on a function that returns a comparable value. Such a comparator can be chained with others.
Assuming your type is called Person, you would have:
Comparator<Person> c = Comparator
.comparing(p -> p.getGroup())
.thenComparing(p -> p.getAge())
.thenComparing(p -> p.getName())
If any of the getters return a primitive type, you have to use - for example - comparingInt
and thenComparingInt
, respectively. You can also use method references:
Comparator<Person> c = Comparator
.comparing(Person::getGroup)
.thenComparing(Person::getAge)
.thenComparing(Person::getName)
But ... if your class has a natural ordering according to these values, you better let it implement the interface Comparable
and write the compare logic in there:
class Person implements Comparable<Person> {
...
@Override
public int compareTo(Person other) {
int compare = Integer.compare(getGroup(), other.getGroup());
if (compare == 0) {
compare = Integer.compare(getAge(), other.getAge());
}
if (compare == 0) {
compare = getName.compareTo(other.getName());
}
return compare;
}
}
This code snippet can also be used in a lambda expression:
list.sort((o1, o2) -> {
int compare = Integer.compare(o1.getGroup(), o2.getGroup());
if (compare == 0) {
compare = Integer.compare(o1.getAge(), o2.getAge());
}
if (compare == 0) {
compare = o1.getName.compareTo(o2.getName());
}
return compare;
});