Como usar o comparator do java

Java fornece duas interfaces para classificar objetos usando membros de dados da classe: 
 

Usando Interface Comparável

Um objeto comparável é capaz de se comparar a outro objeto. A própria classe deve implementar a interface java.lang.Comparable para comparar suas instâncias. Considere uma classe de Cinema que tem membros como, classificação, nome, ano. Suponha que desejamos classificar uma lista de filmes com base no ano de lançamento. Podemos implementar a interface Comparable com a classe Movie e substituir o método compareTo() da interface Comparable. 

// A Java program to demonstrate use of Comparable import java.io.*; import java.util.*; // A class 'Movie' that implements Comparable class Movie implements Comparable<Movie> { private double rating; private String name; private int year; // Used to sort movies by year public int compareTo(Movie m) { return this.year - m.year; } // Constructor public Movie(String nm, double rt, int yr) { this.name = nm; this.rating = rt; this.year = yr; } // Getter methods for accessing private data public double getRating() { return rating; } public String getName() { return name; } public int getYear() { return year; } } // Driver class class Main { public static void main(String[] args) { ArrayList<Movie> list = new ArrayList<Movie>(); list.add(new Movie("Force Awakens", 8.3, 2015)); list.add(new Movie("Star Wars", 8.7, 1977)); list.add(new Movie("Empire Strikes Back", 8.8, 1980)); list.add(new Movie("Return of the Jedi", 8.4, 1983)); Collections.sort(list); System.out.println("Movies after sorting : "); for (Movie movie: list) { System.out.println(movie.getName() + " " + movie.getRating() + " " + movie.getYear()); } } }

Saída: 
 

Movies after sorting : Star Wars 8.7 1977 Empire Strikes Back 8.8 1980 Return of the Jedi 8.4 1983 Force Awakens 8.3 2015

Agora, suponha que queremos classificar os filmes por classificação e nomes também. Quando tornamos um elemento de coleção comparável (fazendo com que ele implemente Comparable), temos apenas uma chance de implementar o método compareTo(). A solução é usar o Comparator. 

Usando o Comparator

Ao contrário de Comparable, Comparator é externo ao tipo de elemento que estamos comparando. É uma classe separada. Criamos várias classes separadas (que implementam Comparator) para comparar por membros diferentes. A classe de coleções tem um segundo método sort() e usa Comparator. O método sort() invoca o compare() para classificar objetos. Para comparar filmes por classificação, precisamos fazer três coisas: 

  1. Crie uma classe que implemente Comparator (e, portanto, o método compare() que faz o trabalho feito anteriormente por compareTo()).
  2. Faça uma instância da classe Comparator.
  3. Chame o método sort() sobrecarregado, fornecendo a ele a lista e a instância da classe que implementa Comparator.
//A Java program to demonstrate Comparator interface import java.io.*; import java.util.*; // A class 'Movie' that implements Comparable class Movie implements Comparable<Movie> { private double rating; private String name; private int year; // Used to sort movies by year public int compareTo(Movie m) { return this.year - m.year; } // Constructor public Movie(String nm, double rt, int yr) { this.name = nm; this.rating = rt; this.year = yr; } // Getter methods for accessing private data public double getRating() { return rating; } public String getName() { return name; } public int getYear() { return year; } } // Class to compare Movies by ratings class RatingCompare implements Comparator<Movie> { public int compare(Movie m1, Movie m2) { if (m1.getRating() < m2.getRating()) return -1; if (m1.getRating() > m2.getRating()) return 1; else return 0; } } // Class to compare Movies by name class NameCompare implements Comparator<Movie> { public int compare(Movie m1, Movie m2) { return m1.getName().compareTo(m2.getName()); } } // Driver class class Main { public static void main(String[] args) { ArrayList<Movie> list = new ArrayList<Movie>(); list.add(new Movie("Force Awakens", 8.3, 2015)); list.add(new Movie("Star Wars", 8.7, 1977)); list.add(new Movie("Empire Strikes Back", 8.8, 1980)); list.add(new Movie("Return of the Jedi", 8.4, 1983)); // Sort by rating : (1) Create an object of ratingCompare // (2) Call Collections.sort // (3) Print Sorted list System.out.println("Sorted by rating"); RatingCompare ratingCompare = new RatingCompare(); Collections.sort(list, ratingCompare); for (Movie movie: list) System.out.println(movie.getRating() + " " + movie.getName() + " " + movie.getYear()); // Call overloaded sort method with RatingCompare // (Same three steps as above) System.out.println("\nSorted by name"); NameCompare nameCompare = new NameCompare(); Collections.sort(list, nameCompare); for (Movie movie: list) System.out.println(movie.getName() + " " + movie.getRating() + " " + movie.getYear()); // Uses Comparable to sort by year System.out.println("\nSorted by year"); Collections.sort(list); for (Movie movie: list) System.out.println(movie.getYear() + " " + movie.getRating() + " " + movie.getName()+" "); } }

Saída : 

Sorted by rating 8.3 Force Awakens 2015 8.4 Return of the Jedi 1983 8.7 Star Wars 1977 8.8 Empire Strikes Back 1980 Sorted by name Empire Strikes Back 8.8 1980 Force Awakens 8.3 2015 Return of the Jedi 8.4 1983 Star Wars 8.7 1977 Sorted by year 1977 8.7 Star Wars 1980 8.8 Empire Strikes Back 1983 8.4 Return of the Jedi 2015 8.3 Force Awakens
  • Comparável se destina a objetos com ordenação natural, o que significa que o próprio objeto deve saber como deve ser ordenado. Por exemplo, role o número de alunos. Considerando que a classificação da interface do Comparator é feita por meio de uma classe separada.
  • Logicamente, a interface Comparable compara “esta” referência com o objeto especificado e o Comparator em Java compara dois objetos de classe diferentes fornecidos.
  • Se qualquer classe implementar a interface Comparable em Java, a coleção desse objeto, List ou Array, pode ser classificada automaticamente usando o método Collections.sort() ou Arrays.sort() e os objetos serão classificados com base na ordem natural definida pelo método CompareTo.
  • Um recurso básico de diferenciação é que, usando comparáveis, podemos usar apenas uma comparação. Enquanto isso, podemos escrever mais de um comparador personalizado conforme você desejar para um determinado tipo, todos usando diferentes interpretações do que significa classificação. Como no exemplo comparável, poderíamos apenas classificar por apenas um atributo, ou seja, ano, mas no comparador, pudemos usar atributos diferentes como classificação, nome e ano também.

Para resumir, se a classificação de objetos precisar ser baseada na ordem natural, use Comparable, enquanto se a classificação precisar ser feita em atributos de objetos diferentes, use Comparator em Java.

 
Este artigo foi contribuído por Souradeep Barua. Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima
 


Both TreeSet and TreeMap store elements in sorted order. However, it is the comparator that defines precisely what sorted order means.

The Comparator interface defines two methods: compare( ) and equals( ). The compare( ) method, shown here, compares two elements for order −

The compare Method

int compare(Object obj1, Object obj2)

obj1 and obj2 are the objects to be compared. This method returns zero if the objects are equal. It returns a positive value if obj1 is greater than obj2. Otherwise, a negative value is returned.

By overriding compare( ), you can alter the way that objects are ordered. For example, to sort in a reverse order, you can create a comparator that reverses the outcome of a comparison.

The equals Method

The equals( ) method, shown here, tests whether an object equals the invoking comparator −

boolean equals(Object obj)

obj is the object to be tested for equality. The method returns true if obj and the invoking object are both Comparator objects and use the same ordering. Otherwise, it returns false.

Overriding equals( ) is unnecessary, and most simple comparators will not do so.

Example

import java.util.*; class Dog implements Comparator<Dog>, Comparable<Dog> { private String name; private int age; Dog() { } Dog(String n, int a) { name = n; age = a; } public String getDogName() { return name; } public int getDogAge() { return age; } // Overriding the compareTo method public int compareTo(Dog d) { return (this.name).compareTo(d.name); } // Overriding the compare method to sort the age public int compare(Dog d, Dog d1) { return d.age - d1.age; } } public class Example { public static void main(String args[]) { // Takes a list o Dog objects List<Dog> list = new ArrayList<Dog>(); list.add(new Dog("Shaggy", 3)); list.add(new Dog("Lacy", 2)); list.add(new Dog("Roger", 10)); list.add(new Dog("Tommy", 4)); list.add(new Dog("Tammy", 1)); Collections.sort(list); // Sorts the array list for(Dog a: list) // printing the sorted list of names System.out.print(a.getDogName() + ", "); // Sorts the array list using comparator Collections.sort(list, new Dog()); System.out.println(" "); for(Dog a: list) // printing the sorted list of ages System.out.print(a.getDogName() +" : "+ a.getDogAge() + ", "); } }

This will produce the following result −

Output

Lacy, Roger, Shaggy, Tammy, Tommy, Tammy : 1, Lacy : 2, Shaggy : 3, Tommy : 4, Roger : 10,

Note − Sorting of the Arrays class is as the same as the Collections.

java_collections.htm

Última postagem

Tag