You are looking for the Comparator
interface. This interface gives you the possibility to sort a collection of many different ways. Its advantage over Comparable
is that you do not have to modify the class whose objects you want to sort, so you can use it even in classes that are not modifiable.
Suppose the class Pessoa
:
class Pessoa {
private String nome;
private int idade;
private float peso;
public Pessoa(String nome, int idade, float peso) {
super();
this.nome = nome;
this.idade = idade;
this.peso = peso;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public int getIdade() {
return idade;
}
public void setIdade(int idade) {
this.idade = idade;
}
public float getPeso() {
return peso;
}
public void setPeso(float peso) {
this.peso = peso;
}
@Override
public String toString() {
return "Pessoa [nome=" + nome + ", idade=" + idade + ", peso=" + peso + "]";
}
}
It has three different attributes and you want to sort a list of objects of type Pessoa
each time using one of the attributes. You will need to create a class for each attribute you want to use as a basis for the comparison, like this:
class OrdenaPorNome implements Comparator<Pessoa> {
@Override
public int compare(Pessoa um, Pessoa dois) {
return um.getNome().compareTo(dois.getNome());
}
}
class OrdenaPorIdade implements Comparator<Pessoa> {
@Override
public int compare(Pessoa um, Pessoa dois) {
return um.getIdade() - dois.getIdade();
}
}
class OrdenaPorPeso implements Comparator<Pessoa> {
@Override
public int compare(Pessoa um, Pessoa dois) {
if(um.getPeso() > dois.getPeso()) return 1;
if(um.getPeso() < dois.getPeso()) return -1;
return 0;
}
}
When you create a class that implements Comparator
you are required to implement the compare()
method whose expected arguments are of the generic type entered between <>
. Note that the implementation I did above involves three different types: a String
, a int
and a float
.
For String
I used the method compareTo()
that the class implements. For int
I subtract one from the other. For float
I made the necessary comparisons to return a coherent value, since it is not possible to subtract because the method expects to return a int
and we would have problems with rounding.
Now it's all for this to run:
public class Comparando {
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<Pessoa>();
pessoas.add(new Pessoa("Pedro", 25, 71));
pessoas.add(new Pessoa("Maria", 27, 60));
pessoas.add(new Pessoa("João", 30, 75.5f));
pessoas.add(new Pessoa("Fernanda", 40, 55));
System.out.println("Ordenando por nome:");
Collections.sort(pessoas, new OrdenaPorNome());
System.out.println(pessoas);
System.out.println("Ordenando por idade:");
Collections.sort(pessoas, new OrdenaPorIdade());
System.out.println(pessoas);
System.out.println("Ordenando por peso:");
Collections.sort(pessoas, new OrdenaPorPeso());
System.out.println(pessoas);
}
}
Output:
Sorting by name:
[Person [name = Maria, age = 27, weight = 60.0], Person [name = Jane, age = 30, weight = Pedro, age = 25, weight = 71.0]]
Sorting by age:
[Person [name = Peter, age = 25, weight = 71.0], Person [name = Maria, age = 27, weight = 60.0] Fernanda, age = 40, weight = 55.0]]
Sorting by weight:
[Person [name = Pedro, age = 40, weight = 55.0], Person [name = Maria, age = 27, weight = 60.0] John, age = 30, weight = 75.5]]