Vergleichbare vs. Komparatorschnittstelle in Java

Dies ist ein interessantes Thema in Java und kann für viele Java-Entwickler verwirrend sein. Deshalb möchte ich einige gängige Beispiele nennen, um die Unterschiede zu veranschaulichen. Anhand des Themennamens sind für uns folgende Dinge offensichtlich:

  • Sowohl Comparator als auch Comparable sind Java-Schnittstellen.
  • Jede Klasse, die diese Schnittstellen verwenden muss, muss in diesen Schnittstellen definierte Methoden implementieren.
  • Beide sind nützlich bei der Reihenfolge von Elementen.
  • Aber es gibt einige Unterschiede in der Art und Weise Komparator und vergleichbar kann in Java verwendet werden. Schauen wir uns zuerst die Comparable- und dann die Comparator-Schnittstelle an.

    Vergleichbare Schnittstelle

    public interface Comparable<Object> {
           public int compareTo(Object obj);
    }
    

    Bei der Implementierung einer vergleichbaren Schnittstelle sollten folgende Punkte beachtet werden:

  • Vergleichbare Schnittstellen können nur zum Vergleich zweier Instanzen desselben Objekts verwendet werden. In der Methode „compareTo()“ können nicht zwei verschiedene Objekte verwendet werden. Dies geht aus der Methode „compareTo()“ hervor, da sie nur über eine Eingabeinstanz verfügt. Es würde mit der aktuellen Instanz verglichen, für die dieses CompareTo() aufgerufen wurde.
  • Die Methode „compareTo()“ muss immer -1 zurückgeben, wenn das aktuelle Objekt kleiner ist als im Parameterobjekt „obj“ übergeben, +1, wenn es größer ist, und 0, wenn es gleich ist. Dies ist sinnvoll, da jeder Vergleich nur zu diesen logischen Schlussfolgerungen führen kann. (Größer, gleich oder kleiner). Dies kann auch als natürliche Reihenfolge der Elemente bezeichnet werden.
  • Comparable existiert im Paket java.lang und Comparator existiert im Paket java.util.
  • Warum sollten wir vergleichbare Schnittstellen in Java implementieren? Hat dies irgendwelche Vorteile?

    Nehmen wir als Beispiel den folgenden Code:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class ComparableTest {
           public static void main(String() args) {
                  List<Double> a = new ArrayList<Double>();
                  a.add(10.45);
                  a.add(20.45);
                  a.add(30.45);
                  a.add(5.45);
                  a.add(4.55);
                  Collections.sort(a);
    
                  for(Double d: a) {
                          System.out.println(d);
                  }
    
                  List<String> s = new ArrayList<String>();
                  s.add("no3");
                  s.add("no2");
                  s.add("no1");
                  s.add("no4");
    
                  Collections.sort(s);
    
                  for(String str: s) {
                          System.out.println(str);
                  }
            }
    }
    

    Code tut nichts anderes, als die Sammlung in natürlicher Reihenfolge zu sortieren. Wenn wir uns jedoch den Code ansehen, übergeben wir verschiedene Typen an die Methode Collection.sort(). Zuerst Double und dann Strings, aber die Methode sort() funktioniert immer noch, was großartig ist.

    Wenn wir uns die Javadocs ansehen, ist die Eingabe für die Methode sort() Comparable a(). Hier ist die vergleichbar und Komparator Schnittstelle kommt ins Spiel. Da die primitiven Datentypen Strings, Double und Integer alle Comparable Interface implementieren, ruft Java beim Aufruf der Methode sort() für diese Objekte intern diese Methode CompareTo() auf, um den Vergleich mit zwei Instanzen desselben Objekts durchzuführen. Schauen Sie sich die Implementierung der Double-Klasse an.

    public class Double implements Comparable<Double> {
    
            public int compareTo(double d1, double d2) {
                  if (d1 < d2)
                     return -1;
                  if (d1 > d2)
                     return 1;
    
                  return 0;
            }
    }
    

    Wie man sehen kann, ruft die Methode sort() intern die Methode CompareTo() von Double auf, wenn die Methode Collections.sort() mit Comparable a() aufgerufen wird, da Double die Schnittstelle Comparable implementiert und die Methode CompareTo überschreibt. In ähnlicher Weise hat String auch die Comparable-Schnittstelle implementiert und daher funktioniert Collections.sort() auch mit Strings.

    Eine sehr kraftvolle Idee. Mithilfe dieser vergleichbaren Schnittstelle konnten wir die Methode sort() unabhängig von Daten machen Das heißt, es kann jede Art von Objekt sortieren, wenn dieses bestimmte Objekt die Comparable-Schnittstelle implementiert. Das könnte etwas verwirrend sein, aber wenn Sie dasselbe Programm für sich selbst ausführen, werden Sie den Nutzen der Comparable-Schnittstelle erkennen.

    Nur einfache primitive Objekte und wenige andere Objekte implementieren Comparable Interface. Wenn wir möchten, dass unser neues Objekt aufgerufen wird, wenn die Methode sort() aufgerufen wird, müssen wir unsere eigene vergleichbare Schnittstelle implementieren.

    Schauen wir uns ein Beispiel an, um die vergleichbare Schnittstelle zu veranschaulichen. Eine neue Klasse ComparableTest, die das Comparable Interface implementiert und die Methode CompareTo() mit dem zuvor dargestellten logischen Vergleich überschreibt.

    Kundenprogramm:

    import java.util.Arrays;
    
    public class TestCompareTo {
    
         public static void main(String() args) {
                ComparableTest() cmpares = new ComparableTest(3);
    
                ComparableTest one = new ComparableTest(10);
                ComparableTest two = new ComparableTest(50);
                ComparableTest three = new ComparableTest(30);
    
                cmpares(0) = one;
                cmpares(1) = two;
                cmpares(2) = three;
    
                Arrays.sort(cmpares);
    
                for(ComparableTest test: cmpares) {
                    System.out.println(test.getScores());
                }
    
           }
    
    }
    

    Im Client-Programm konnte ich die neue Klasse ComparableTest zur Methode Array.sort() hinzufügen und die Ergebnisse in natürlicher Reihenfolge anordnen, da die Klasse ComparableTest die Schnittstelle Comparable implementiert.

    Kommen wir nun zur Komparatorschnittstelle.

    Komparatorschnittstelle

    Bei einem kurzen Blick auf eine vergleichbare Schnittstelle sind die Hauptmängel folgende:

  • Mit der Comparable-Schnittstelle können wir nur die natürliche Reihenfolge der Elemente erreichen, was wäre, wenn wir es mit verschiedenen Schlüsseln sortieren würden? Beispielsweise kann die String-Reihenfolge eine Reihenfolge ohne Berücksichtigung der Groß-/Kleinschreibung oder eine natürliche Reihenfolge sein.
  • Was ist auch, wenn wir eine andere Reihenfolge (absteigende Reihenfolge) für die integrierte Klasse java.lang.Integer, Double wünschen? java.lang.Integer, java.lang.Double können nicht umgeschrieben werden, da dies alles endgültige Klassen sind. Und mit der Comparable-Schnittstelle ist nur eine natürliche Reihenfolge der Elemente möglich. Also Um unser Ziel der individuellen Anordnung von Elementen und auch der Anordnung mit unterschiedlichen Schlüsseln zu erreichen, verwenden wir die Comparator-Schnittstelle.
  • public interface Comparator<Object> {
           public int compare (Object item1, Object item2);
    }
    

    In Java integrierte Beispiele:

     String s1() = new String(2);
        s1(0) = "labEl";
        s1(1) = "LabEl2";
    
        Arrays.sort(s1);
        Arrays.sort(s1, String.CASE_INSENSITIVE_ORDER);
    

    Der obige Code ist leicht zu verstehen. Es ordnet String-Arrays mit natürlicher Reihenfolge und auch mit Groß-/Kleinschreibung. Wenn Strings nur Comparable Interface verwendet hätten, wäre nur eine natürliche Reihenfolge möglich gewesen. Da String aber auch die Comparator-Schnittstelle implementiert, kann die Reihenfolge mit unterschiedlichen Schlüsseln erfolgen, beispielsweise ohne Berücksichtigung der Groß- und Kleinschreibung.

    Schauen wir uns ein Beispiel an, wie dies erreicht werden kann:

    import java.util.Comparator;
    
    public class ComparatorTest {
    
         public static Comparator ASC_ORDER = new AscOrder();
         public static Comparator DESC_ORDER = new DescOrder();
    
         private Integer numbers;
    
         public ComparatorTest(int num) {
               this.numbers = num;
         }
    
         public int getNumbers() {
               return numbers;
         }
    
         public void setNumbers(int numbers) {
               this.numbers = numbers;
         }
    
         private static class AscOrder implements Comparator {
                 public int compare(ComparatorTest one,
                                            ComparatorTest two)
                 {
                       if (one.numbers < two.numbers) {
                              return -1;
                       }
                       else if (one.numbers > two.numbers) {
                               return 1;
                        }
                        return 0;
    
                 }
           }
    
           private static class DescOrder implements Comparator {
                  public int compare(ComparatorTest one,
                                                ComparatorTest two)
                  {
                          if (one.numbers > two.numbers) {
                                 return -1;
                          }
                          else if (one.numbers < two.numbers) {
                                 return 1;
                          }
                          return 0;
                  }
           }
    
    }
    

    Der Code implementiert die Comparator-Schnittstelle und verwendet zwei Klassen, um nach zwei verschiedenen Schlüsseln zu ordnen – aufsteigende und absteigende Reihenfolge. Die absteigende Reihenfolge bewirkt das Gegenteil der aufsteigenden Reihenfolge und beide Klassen überschreiben die Methode „compare()“ als Teil der Comparator-Schnittstelle. ASC_ORDER und DESC_ORDER können vom Client-Programm als Schlüssel verwendet werden, um die entsprechende Bestellung einzuleiten.

    Kundenprogramm:

    import java.util.Arrays;
    
    public class TestCompareTo {
    
           public static void main(String() args) {
                  String s1() = new String(2);
                  s1(0) = "label";
                  s1(1) = "label2";
    
                  Arrays.sort(s1);
                  Arrays.sort(s1, String.CASE_INSENSITIVE_ORDER);
    
                  ComparatorTest() cmpares = new ComparatorTest(4);
    
                  ComparatorTest one = new ComparatorTest(10);
                  ComparatorTest two = new ComparatorTest(50);
                  ComparatorTest three = new ComparatorTest(30);
                  ComparatorTest four = new ComparatorTest(20);
    
                  cmpares(0) = one;
                  cmpares(1) = two;
                  cmpares(2) = three;
                  cmpares(3) = four;
    
                  Arrays.sort(cmpares, ComparatorTest.ASC_ORDER);
    
                  for(ComparatorTest test: cmpares) {
                          System.out.println(test.getNumbers());
                  }
    
                  Arrays.sort(cmpares, ComparatorTest.DESC_ORDER);
    
                  for(ComparatorTest test: cmpares) {
                          System.out.println(test.getNumbers());
                  }
    
           }
    
    }
    

    Wie aus dem obigen Code ersichtlich ist, konnten wir, genau wie String.CASE_INSENSITIVE_ORDER, zwei verschiedene Reihenfolgen erreichen – ComparatorTest.ASC_ORDER und ComparatorTest.DESC_ORDER. Der Kunde kann jede gewünschte Bestellung wählen.

    Zusammenfassung

    Das war’s für die Comparable- und Comparator-Schnittstelle. Ich hoffe, dieses Thema ist jetzt viel klarer als zu Beginn des Lesens dieses Artikels. Üben Sie einige Beispiele, um diese Konzepte klarer zu machen. Danke fürs Lesen. Veröffentlichen Sie Ihre Kommentare/Kritik im Abschnitt „Kommentare“.

    Dieser Artikel wurde ursprünglich unter veröffentlicht Java-Tutorials – Lasst uns ins Meer springenhier mit Genehmigung des Autors und als Teil des JBC-Programms erneut veröffentlicht.

    Kommentar verfassen

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

    Nach oben scrollen