Yes, you can do everything in one sort
.
If you want to make a specific sort, you can use Collections.sort
passing a Comparator
as a parameter.
The idea of Comparator
is to provide a customized comparison form. You simply implement the method compare
, receiving two objects obj1
and obj2
and returns the following:
- if
obj1
is "less" than obj2
(that is, if in an ordination obj1
must come before obj2
), returns a negative number
- if
obj1
is "greater" than obj2
(that is, if in an ordination obj1
must come after obj2
), returns a positive number
- If it makes the order between them, returns zero
Then given a list of objects, just implement a Comparator
that follows the rules you need:
List<Candidatura> list = new ArrayList<>();
// adiciona Candidaturas na lista
Collections.sort(list, new Comparator<Candidatura>() {
@Override
public int compare(Candidatura c1, Candidatura c2) {
int cmp = Double.compare(c2.getMedia(), c1.getMedia());
if (cmp == 0) { // se as médias forem iguais, desempata pelo menor preço
cmp = Double.compare(c1.getValorPretendido(), c2.getValorPretendido());
if (cmp == 0) { // se os preços forem iguais, desempata pela menor data
cmp = c1.getDate().compareTo(c2.getDate());
}
}
return cmp;
}
});
System.out.println(list.get(0));
First I compare the averages. If they are equal (and only if they are equal), I compare the price. If the price is equal, I compare the dates.
Notice that for the average I compared c2
with c1
. If I reversed the order, they would be in ascending order, but when reversed, they are in nonexistent order. This means that the highest averages will be at the beginning of the list. Already for the price and date, I put c1
first, because the lowest values must be.
In the end, the element you want will be in the first position (the one that has the highest average, and in the case of a tie on average, the one that has the lowest price, and in the case of a tie on price and the average, the one that has the lowest date). Also remembering that if you have tied in the first position (two elements with the same average, price and date), will be returned what appears first in the list (since the ordering is guaranteed stable).
From Java 8 you can also use the syntax of lambda:
Collections.sort(list, (c1, c2) -> {
int cmp = Double.compare(c2.getMedia(), c1.getMedia());
if (cmp == 0) { // se as médias forem iguais, desempata pelo menor preço
cmp = Double.compare(c1.getValorPretendido(), c2.getValorPretendido());
if (cmp == 0) { // se os preços forem iguais, desempata pela menor data
cmp = c1.getDate().compareTo(c2.getDate());
}
}
return cmp;
});
Thank you very much, that was my doubt whether it was possible to do it or not. Thank you very much
– Pedro Moreira