


Vergleichende Einführung in Comparable und Comparator in Java (Codebeispiel)
Dieser Artikel bietet Ihnen eine vergleichende Einführung (Codebeispiel) zwischen Comparable und Comparator. Er hat einen gewissen Referenzwert.
1. Übersicht
Die Sortierung in Java erfolgt über die beiden Schnittstellen Comparable und Comparator.
Vergleichbar bedeutet, dass es sortiert werden kann und Objekte von Klassen, die diese Schnittstelle implementieren, automatisch über die Sortierfunktion verfügen.
Komparator stellt einen Komparator dar, der für das Objekt der Zielklasse definiert ist. Im Allgemeinen wird dieser Komparator als Parameter übergeben.
2. Vergleichbar
Die chinesische Bedeutung von Vergleichbar ist, dass es sortiert werden kann, was bedeutet, dass es die Sortierfunktion unterstützt. Solange unsere Klasse diese Schnittstelle implementiert, können Objekte dieser Klasse automatisch sortiert werden. Und diese Ordnung nennt man die natürliche Ordnung der Klassen. Listen von Objekten dieser Klasse können nach Collections.sort und Arrays.sort sortiert werden. Gleichzeitig sind Instanzen dieser Klasse als Schlüssel einer sortierten Karte und Elemente einer sortierten Menge qualifiziert.
Wenn a und b beide Instanzen der Klasse C sind, die die Comparable-Schnittstelle implementiert, wird sie nur dann aufgerufen, wenn das Ergebnis von a.compareTo(b) mit dem Ergebnis von a.equals(b) übereinstimmt Klasse C. Die natürliche Ordnung steht im Einklang mit Gleichen. Es wird dringend empfohlen, die natürliche Reihenfolge der Klasse mit dem Ergebnis von equal in Einklang zu halten, denn wenn sie inkonsistent sind, ändert sich das Verhalten einer sortierten Karte mit Objekten dieser Klasse als Schlüssel und einer sortierten Menge mit Objekten dieser Klasse als Elementen benimm dich seltsam.
Wenn beispielsweise für eine sortierte Menge, die die Comparable-Schnittstelle implementiert, das Ergebnis von a.equals(b) falsch ist und a.compareTo(b)==0, dann ist die zweite die Additionsoperation von Elementen wird fehlschlagen, weil aus Sicht der sortierten Menge die beiden in der Sortierung konsistent sind und keine doppelten Elemente gespeichert werden.
Tatsächlich stimmt die natürliche Reihenfolge der Klassen in Java grundsätzlich mit Gleichen überein, mit Ausnahme von BigDecimal, da die natürliche Reihenfolge in BigDecimal mit den Gleichen von Elementen mit demselben Wert, aber unterschiedlicher Genauigkeit (z. B. 4) übereinstimmt und 4,00) .
Quellcode-Analyse
public interface Comparable<T> { public int compareTo(T o); }
Sie können dem Quellcode entnehmen, dass die Schnittstelle nur eine abstrakte Methode „compareTo“ hat. Diese Methode dient hauptsächlich dazu, die Art und Weise zu definieren, wie unsere Klassen sortiert werden. Die Methode „compareTo“ wird verwendet, um das aktuelle Element a mit dem angegebenen Element b zu vergleichen. Wenn a > int <
3. Komparator
Komparator wird auf Chinesisch als Komparator übersetzt. Er kann als Parameter an die Methoden Collections.sort und Arrays.sort übergeben werden, um einen bestimmten Wert anzugeben Klassenobjekt. Sortieren nach. Gleichzeitig kann auch die Sortiermethode für sortierte Sätze und sortierte Karten angegeben werden.
Ähnlich wie bei Comparable muss bei der Angabe eines Komparators im Allgemeinen sichergestellt werden, dass das Vergleichsergebnis mit dem Gleichheitsergebnis übereinstimmt. Wenn sie inkonsistent sind, ändert sich auch das Verhalten des entsprechenden sortierten Satzes und der sortierten Karte seltsam.
Es wird empfohlen, dass die implementierte Komparatorklasse auch die Schnittstelle java.io.Serializable implementiert, um über Serialisierungsfunktionen zu verfügen, da sie als Sortiermethode für serialisierte Datenstrukturen (TreeSet, TreeMap) verwendet werden kann.
Quellcode-Analyse
@FunctionalInterface public interface Comparator<T> { // 唯一的抽象方法,用于定义比较方式(即排序方式) // o1>o2,返回1;o1=o2,返回0;o1<o2,返回-1 int compare(T o1, T o2); boolean equals(Object obj); // 1.8新增的默认方法:用于反序排列 default Comparator<T> reversed() { return Collections.reverseOrder(this); } // 1.8新增的默认方法:用于构建一个次级比较器,当前比较器比较结果为0,则使用次级比较器比较 default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator<T> & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; } // 1.8新增默认方法:指定次级比较器的 // keyExtractor表示键提取器,定义提取方式 // keyComparator表示键比较器,定义比较方式 default <U> Comparator<T> thenComparing( Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator) { return thenComparing(comparing(keyExtractor, keyComparator)); } // 1.8新增默认方法:用于执行键的比较,采用的是由键对象内置的比较方式 default <U extends Comparable<? super U>> Comparator<T> thenComparing( Function<? super T, ? extends U> keyExtractor) { return thenComparing(comparing(keyExtractor)); } // 1.8新增默认方法:用于比较执行int类型的键的比较 default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) { return thenComparing(comparingInt(keyExtractor)); } // 1.8新增默认方法:用于比较执行long类型的键的比较 default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) { return thenComparing(comparingLong(keyExtractor)); } // 1.8新增默认方法:用于比较执行double类型的键的比较 default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) { return thenComparing(comparingDouble(keyExtractor)); } // 1.8新增静态方法:用于得到一个相反的排序的比较器,这里针对的是内置的排序方式(即继承Comparable) public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() { return Collections.reverseOrder(); } // 1.8新增静态方法:用于得到一个实现了Comparable接口的类的比较方式的比较器 // 简言之就是将Comparable定义的比较方式使用Comparator实现 @SuppressWarnings("unchecked") public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE; } // 1.8新增静态方法:得到一个null亲和的比较器,null小于非null,两个null相等,如果全不是null, // 则使用指定的比较器比较,若未指定比较器,则非null全部相等返回0 public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) { return new Comparators.NullComparator<>(true, comparator); } // 1.8新增静态方法:得到一个null亲和的比较器,null大于非null,两个null相等,如果全不是null, // 则使用指定的比较器比较,若未指定比较器,则非null全部相等返回0 public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) { return new Comparators.NullComparator<>(false, comparator); } // 1.8新增静态方法:使用指定的键比较器用于执行键的比较 public static <T, U> Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator) { Objects.requireNonNull(keyExtractor); Objects.requireNonNull(keyComparator); return (Comparator<T> & Serializable) (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2)); } // 1.8新增静态方法:执行键比较,采用内置比较方式,key的类必须实现Comparable public static <T, U extends Comparable<? super U>> Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); } // 1.8新增静态方法:用于int类型键的比较 public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2)); } // 1.8新增静态方法:用于long类型键的比较 public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2)); } // 1.8新增静态方法:用于double类型键的比较 public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2)); } }
Es gibt nur zwei Methoden in der alten Version von Comparator, nämlich die ersten beiden Methoden. Alle nachfolgenden Standardmethoden sind die neuen Methoden, die in 1.8 hinzugefügt wurden Schnittstelle kann Standardmethoden hinzufügen. Selbst bei so vielen Methoden ist die Schnittstelle immer noch eine funktionale Schnittstelle, und Compare wird zum Definieren der Vergleichsmethode verwendet.
4. Vergleich zwischen den beiden
Comparable kann als interner Komparator und Comparator als externer Komparator betrachtet werden.
Eine Klasse kann Ordnung schaffen, indem sie die Comparable-Schnittstelle implementiert, oder sie kann Ordnung schaffen, indem sie einen zusätzlichen Komparator angibt.
Die Funktionen der beiden sind eigentlich die gleichen, also vermischen Sie sie nicht.
Sehen wir uns ein Beispiel an:
Definieren Sie zunächst ein Modell: Benutzer
public class User implements Serializable, Comparable<User> { private static final long serialVersionUID = 1L; private int age; private String name; public User (){} public User (int age, String name){ this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int compareTo(User o) { return this.age - o.age; } @Override public String toString() { return "[user={age=" + age + ",name=" + name + "}]"; } }
Definieren Sie dann eine Comparator-Implementierungsklasse MyComparator
public class MyComparator implements Comparator<User> { @Override public int compare(User o1, User o2) { return o1.getName().charAt(0)-o2.getName().charAt(0); } }
Zuletzt die Testklasse : Main
public class Main { public static void main(String[] args) { User u1 = new User(12, "xiaohua"); User u2 = new User(10, "abc"); User u3 = new User(15,"ccc"); User[] users = {u1,u2,u3}; System.out.print("数组排序前:"); printArray(users); System.out.println(); Arrays.sort(users); System.out.print("数组排序1后:"); printArray(users); System.out.println(); Arrays.sort(users, new MyComparator()); System.out.print("数组排序2后:"); printArray(users); System.out.println(); Arrays.sort(users, Comparator.reverseOrder());// 针对内置的排序进行倒置 System.out.print("数组排序3后:"); printArray(users); } public static void printArray (User[] users) { for (User user:users) { System.out.print(user.toString()); } } }
Das laufende Ergebnis ist:
数组排序前:[user={age=12,name=xiaohua}][user={age=10,name=abc}][user={age=15,name=ccc}] 数组排序1后:[user={age=10,name=abc}][user={age=12,name=xiaohua}][user={age=15,name=ccc}] 数组排序2后:[user={age=10,name=abc}][user={age=15,name=ccc}][user={age=12,name=xiaohua}] 数组排序3后:[user={age=15,name=ccc}][user={age=12,name=xiaohua}][user={age=10,name=abc}]
Durch das obige Beispiel haben wir eine Schlussfolgerung, das heißt, es gibt zwei Möglichkeiten, die Priorität der Sortierung zu definieren, den Comparator-Komparator hat Vorrang vor der internen Sortierung Vergleichbar.
5. Zusammenfassung
Comparable ist sortierbar, und Objekte von Klassen, die diese Schnittstelle implementieren, verfügen automatisch über die sortierbare Funktion.
Comparator ist ein Komparator. Durch die Implementierung dieser Schnittstelle kann eine Sortiermethode für eine bestimmte Klasse definiert werden.
Wenn Comparator und Comparable gleichzeitig vorhanden sind, hat ersteres eine höhere Priorität.
Das obige ist der detaillierte Inhalt vonVergleichende Einführung in Comparable und Comparator in Java (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

PHP und Python haben jeweils ihre eigenen Vorteile, und die Wahl sollte auf Projektanforderungen beruhen. 1.PHP eignet sich für die Webentwicklung mit einfacher Syntax und hoher Ausführungseffizienz. 2. Python eignet sich für Datenwissenschaft und maschinelles Lernen mit präziser Syntax und reichhaltigen Bibliotheken.

PHP ist eine Skriptsprache, die auf der Serverseite weit verbreitet ist und insbesondere für die Webentwicklung geeignet ist. 1.PHP kann HTML einbetten, HTTP -Anforderungen und Antworten verarbeiten und eine Vielzahl von Datenbanken unterstützt. 2.PHP wird verwendet, um dynamische Webinhalte, Prozessformdaten, Zugriffsdatenbanken usw. mit starker Community -Unterstützung und Open -Source -Ressourcen zu generieren. 3. PHP ist eine interpretierte Sprache, und der Ausführungsprozess umfasst lexikalische Analyse, grammatikalische Analyse, Zusammenstellung und Ausführung. 4.PHP kann mit MySQL für erweiterte Anwendungen wie Benutzerregistrierungssysteme kombiniert werden. 5. Beim Debuggen von PHP können Sie Funktionen wie error_reporting () und var_dump () verwenden. 6. Optimieren Sie den PHP-Code, um Caching-Mechanismen zu verwenden, Datenbankabfragen zu optimieren und integrierte Funktionen zu verwenden. 7

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.
