Sort a list of objects by more than one attribute

3

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

    
asked by anonymous 01.12.2014 / 21:27

2 answers

3

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);
    
01.12.2014 / 21:51
2

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 ?

    
01.12.2014 / 21:36