Java proporciona dos interfaces para ordenar objetos usando miembros de datos de la clase:
- Comparable
- comparador
Uso de interfaz comparable
Un objeto comparable es capaz de compararse con otro objeto. La clase en sí debe implementar la interfaz java.lang.Comparable para comparar sus instancias.
Considere una clase de película que tiene miembros como, calificación, nombre, año. Supongamos que deseamos ordenar una lista de películas según el año de lanzamiento. Podemos implementar la interfaz Comparable con la clase Movie y anulamos el método compareTo() de la interfaz Comparable.
Java
// 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()); } } }
Producción:
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
Ahora, supongamos que también queremos ordenar las películas por su calificación y nombres. Cuando hacemos que un elemento de colección sea comparable (haciendo que implemente Comparable), solo tenemos una oportunidad de implementar el método compareTo(). La solución es usar Comparator.
Usando el comparador
A diferencia de Comparable, Comparator es externo al tipo de elemento que estamos comparando. Es una clase separada. Creamos múltiples clases separadas (que implementan Comparator) para comparar por diferentes miembros.
La clase Collections tiene un segundo método sort() y toma Comparator. El método sort() invoca compare() para ordenar objetos.
Para comparar películas por calificación, debemos hacer 3 cosas:
- Cree una clase que implemente Comparator (y, por lo tanto, el método compare() que realiza el trabajo que anteriormente realizaba compareTo()).
- Cree una instancia de la clase Comparator.
- Llame al método sort() sobrecargado, dándole tanto la lista como la instancia de la clase que implementa Comparator.
Java
//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()+" "); } }
Producción :
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
- Comparable está destinado a objetos con ordenamiento natural, lo que significa que el objeto en sí debe saber cómo debe ordenarse. Por ejemplo Roll Numbers de estudiantes. Mientras que la clasificación de la interfaz Comparator se realiza a través de una clase separada.
- Lógicamente, la interfaz Comparable compara «esta» referencia con el objeto especificado y Comparator en Java compara dos objetos de clase diferentes provistos.
- Si alguna clase implementa una interfaz comparable en Java, la colección de ese objeto, ya sea List o Array, se puede ordenar automáticamente utilizando el método Collections.sort() o Arrays.sort() y los objetos se ordenarán según el orden natural definido por el método CompareTo.
- Un rasgo diferenciador básico es que usando comparables podemos usar solo una comparación. Mientras que podemos escribir más de un comparador personalizado como desee para un tipo determinado, todos usando diferentes interpretaciones de lo que significa la clasificación. Al igual que en el ejemplo comparable, solo podíamos ordenar por un solo atributo, es decir, año, pero en el comparador, también podíamos usar diferentes atributos como calificación, nombre y año.
Para resumir, si la clasificación de objetos debe basarse en el orden natural, use Comparable, mientras que si la clasificación debe realizarse en atributos de diferentes objetos, use Comparator en Java.
Este artículo es una contribución de Souradeep Barua. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA