Comparable vs Comparador en Java

 

Java proporciona dos interfaces para ordenar objetos usando miembros de datos de la clase: 
 

  1. Comparable
  2. 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: 
 

  1. Cree una clase que implemente Comparator (y, por lo tanto, el método compare() que realiza el trabajo que anteriormente realizaba compareTo()).
  2. Cree una instancia de la clase Comparator.
  3. 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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *