Question :
How to sort a list of objects by more than one attribute? The first is the ordering of the score, then as a tiebreaker we have the number of victory and then the balance of goals.
Something like this:
Pontuacao pontuacao = new Pontuacao(pontos, vitórias, saldo de gols);
List lista = new List();
Pontuacao timeA = new Pontuacao(14, 6, 20);
lista.add(timeA);
Pontuacao timeB = new Pontuacao(18, 3, 21);
lista.add(timeB);
Pontuacao timeC = new Pontuacao(14, 6, 22);
lista.add(timeC);
Pontuacao timeD = new Pontuacao(15, 7, 11);
lista.add(timeD);
lista.sort;
Result:
1st) timeB // Highest score
2nd) timeD // Second highest score
3º) timeC // Highest goal difference
4th) timeA
Answer :
To do this, you can use the sort
method of the Collections
class. Through it, you can create blockwise ordering logic:
List<Pontuacao> pontuacoes = new ArrayList<>();
pontuacoes.add(new Pontuacao(14, 6, 20));
pontuacoes.add(new Pontuacao(18, 3, 21));
pontuacoes.add(new Pontuacao(14, 6, 22));
pontuacoes.add(new Pontuacao(15, 7, 11));
Collections.sort(pontuacoes, new Comparator<Pontuacao>() {
@Override
public int compare(Pontuacao lhs, Pontuacao rhs) {
if(lhs.getPontos != rhs.getPontos)
return Integer.compare(lhs.getPontos(), rhs.getPontos());
else if(lhs.getVitorias() != rhs.getVitorias())
return Integer.compare(lhs.getVitorias(), rhs.getVitorias());
return Integer.compare(lhs.getSaldoDeGols(), rhs.getSaldoDeGols());
}
});
Your Scoring object can even implement the Comparable<T>
interface to make this code more organized:
class Pontuacao implements Comparable<Pontuacao> {
private int pontos;
private int vitorias;
private int saldoDeGols;
public Pontuacao(int pontos, int vitorias, int saldoDeGols) {
this.pontos = pontos;
this.vitorias = vitorias;
this.saldoDeGols = saldoDeGols;
}
public int getPontos() {
return pontos;
}
public void setPontos(int pontos) {
this.pontos = pontos;
}
public int getVitorias() {
return vitorias;
}
public void setVitorias(int vitorias) {
this.vitorias = vitorias;
}
public int getSaldoDeGols() {
return saldoDeGols;
}
public void setSaldoDeGols(int saldoDeGols) {
this.saldoDeGols = saldoDeGols;
}
@Override
public int compareTo(@NonNull Pontuacao another) {
if(another.getPontos() != getPontos())
return Integer.compare(another.getPontos(), getPontos());
else if(another.getVitorias() != getVitorias())
return Integer.compare(another.getVitorias(), getVitorias());
return Integer.compare(another.getSaldoDeGols(), getSaldoDeGols());
}
}
Then sort is simplified:
List<Pontuacao> pontuacoes = new ArrayList<>();
pontuacoes.add(new Pontuacao(14, 6, 20));
pontuacoes.add(new Pontuacao(18, 3, 21));
pontuacoes.add(new Pontuacao(14, 6, 22));
pontuacoes.add(new Pontuacao(15, 7, 11));
Collections.sort(pontuacoes);
Make your class Pontuacao
implement the Comparable<Pontuacao>
interface and implement the compareTo()
method on it.
Example with two criteria, with criterion 1 being more important and criterion 2 being less important:
public int compareTo(Pontuacao outro) {
int resultado = outro.getCriterio1() - this.getCriterio1();
if (resultado == 0) {
resultado = outro.getCriterio2() - this.getCriterio2();
}
return resultado;
}
Why do not you have a null check ?