Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung des Beispielcodes der Java Comparable-Schnittstelle

Detaillierte Erläuterung des Beispielcodes der Java Comparable-Schnittstelle

黄舟
黄舟Original
2017-03-20 11:09:461432Durchsuche

Dieser Artikel ist Teil des kostenlosen Java 8-Kurses zu Clean Code-Prinzipien.

In diesem Artikel werden wir über die Java ComparableSchnittstelle sprechen.

Es gibt auch ein gutes Video, das Sie hier klicken können.

Wofür wird die Comparable-Schnittstelle verwendet?

Wie sollen wir Dinge vergleichen und ordnen? Diese Frage klingt vielleicht etwas verwirrend, aber ich hoffe, dass Sie ernsthaft darüber nachdenken. Wir haben zum Beispiel eine Gruppe Äpfel:

Beispiel 1

Wie sortieren wir sie? Wollen wir nach Gewicht sortieren? Wenn ja, sind sie vom leichtesten zum schwersten oder vom schwersten zum leichtesten sortiert? Wenn wir sie sortieren, müssen wir das Gewicht der beiden Äpfel wiederholt vergleichen, bis alle Äpfel richtig sortiert sind. Apple 1 ist schwerer als Apple 2? Ist es also schwerer als das iPhone 3? Wir müssen so lange vergleichen, bis die Sortierung abgeschlossen ist. Die Comparable-Schnittstelle kann uns dabei helfen, dieses Ziel zu erreichen. Comparable selbst kann Objekte nicht sortieren, die von der Schnittstelle definierte Methode int CompareTo(T) jedoch schon.

So funktioniert CompareTo(T)

Beginnen wir damit, mithilfe der Methode CompareTo() herauszufinden, welcher Apfel schwerer ist.

Beispiel 2

Die Methode „compareTo()“ funktioniert, indem sie einen int-Wert zurückgibt – entweder positiv, negativ oder Null. Es vergleicht Objekte, indem es das Objekt als Argument aufruft. Negative Zahlen zeigen an, dass das aufgerufene Objekt „leichter“ ist als das Argument. Wenn wir Äpfel nach Größe vergleichen würden, würde der obige Aufruf eine negative Zahl zurückgeben, z. B. -400, da rote Äpfel kleiner sind als grüne Äpfel. Wenn die beiden Äpfel das gleiche Gewicht haben, gibt der Aufruf 0 zurück. Wenn der rote Apfel schwerer ist, gibt CompareTo() eine positive Zahl zurück, z. B. 68.

Flexibilität von CompareTo()

Wenn wir die Methode CompareTo() oben wiederholt aufrufen, können wir nach Größe sortieren, was großartig ist, aber nicht das Ende der Geschichte. Was wäre, wenn wir Äpfel nach Farbe sortieren möchten? Oder liegt es am Gewicht? Wir können es auch schaffen. Der Punkt ist, dass unser Kunde – nennen wir ihn Fat Farmer (siehe Beispiel 3) – genau definieren muss, wie die Äpfel sortiert werden müssen, bevor wir mit der Entwicklung beginnen.

Beispiel 3

Er kann dies tun, indem er diese beiden Fragen beantwortet:

  1. Er Wie willst du Apple zum Sortieren? Welche Eigenschaften möchte er von uns vergleichen?

  2. Was bedeuten in diesem Zusammenhang „kleiner als“, „gleich“ und „größer als“?

Sie können auch mehrere Funktionen nutzen, über die wir später sprechen werden.

Beispiel 1: Äpfel nach Gewicht sortieren

In diesem ersten Beispiel sortieren wir Äpfel nach Gewicht. Alles was es braucht ist eine Zeile Code.

Collections.sort(apples);

Beispiel 4

Die obige Codezeile kann die gesamte Sortierarbeit für uns erledigen, solange wir im Voraus definieren, wie die Äpfel sortiert werden sollen (dies erfordert mehrere Codezeilen). ).

Beginnen wir mit dem Schreiben der Apfelkategorie.

public class Apple implements Comparable {
    private String variety;
    private Color color;
    private int weight;
    @Override
    public int compareTo(Apple other) {
        if (this.weight < other.weight) {
            return -1;
        }
        if (this.weight == other.weight) {
            return 0;
        }
        return 1;
    }
}

Beispiel 5

Dies ist die erste Version der Apple-Klasse. Da wir die Methode „compareTo“ verwenden und Äpfel sortieren, habe ich die Schnittstelle „Comparable“ implementiert. In dieser ersten Version vergleichen wir Objekte nach Gewicht. In unserer Methode „compareTo()“ schreiben wir eine if-Bedingung, die besagt, dass eine negative Zahl zurückgegeben wird, wenn dieser Apfel weniger wiegt als die anderen. Um es einfach zu halten, gehen wir davon aus, dass er -1 ist. Denken Sie daran, dass dies bedeutet, dass dieser Apple leichter ist als der „andere“ Apple. In der zweiten if-Anweisung geben wir an, dass eine 0 zurückgegeben wird, wenn die Äpfel das gleiche Gewicht haben. Wenn dieser Apfel weder leichter noch gleich schwer ist, kann er natürlich nur schwerer sein als andere Äpfel. In diesem Fall geben wir eine positive Zahl zurück, die als 1 angenommen wird.

例2:通过多个特征排序苹果

正如我前面提到的,我们还可以使用compareTo()比较多个特征。比方说,我们第一通过品种排序苹果,但如果两个苹果是同一品种,那么我们就按颜色排序。最后,如果这两个特性相同,那么我们将按重量排序。虽然我们可以手动实现这件事,就像我在最后一个例子中做的那样,但是其实可以用一种简洁得多的方式实现。一般来说,最好是重用现有的代码,而不是自己写。我们可以在Integer、String和枚举类中使用compareTo方法来比较值。由于我们没有使用Integer对象,用了int,所以我们不得不使用来自于Integer包装器类的一个静态的helper方法来比较两个值。

public class Apple implements Comparable {
    private String variety;
    private Color color;
    private int weight;
    @Override
    public int compareTo(Apple other) {
        int result = this.variety.compareTo(other.variety);
        if (result != 0) {
            return result;
        }
        if (result == 0) {
            result = this.color.compareTo(other.color);
        }
        if (result != 0) {
            return result;
        }
        if (result == 0) {
            result = Integer.compare(this.weight, other.weight);
        }
        return result;
    }
}

例6

在例6中,我们比较了客户指定的苹果的第一特性,它们的品种。如果compareTo()调用的结果为非零,那么我们返回值。否则,我们调用另一个compareTo()直到得到一个非零值,或者直到已经比较完这三个特征。尽管此代码可以工作,但它不是最有效或干净的解决方案。在例3中,我们重构我们的代码,使其更简单。

@Override
public int compareTo(Apple other) {
     int result = this.variety.compareTo(other.variety);
     if (result == 0) {
          result = this.color.compareTo(other.color);
     }
     if (result == 0) {
          result = Integer.compare(this.weight, other.weight);
     }
     return result;
}

例7

正如你所看到的,这大大减少了代码,并且每一次比较只要一行代码。如果一个compareTo()调用的结果是零,那么我们就转移到下一个相同if语句的比较中。顺便说一句,这是成为Clean Coder的一个很好的例子。通常情况下,你不需要立即写出干净的代码;你可以从一个粗略的想法开始,使其可以工作,然后不断改进,直到你尽可能得让它干净就可以了。

Comparable,hashCode以及Equals

你可能会注意到compareTo()看起来有点像hashCode()和equals()方法。但是,它们有一个重要的区别。对于hashCode()和equals()方法,比较个体属性的顺序不影响返回的值,但是,在compareTo()中,通过你比较对象的顺序来定义对象的顺序。

结论

在结论中我只想强调Comparable接口是多么的重要。它既用于java.util.Arrays,也用于java.util.Collections实用程序类,来排序元素和搜索排序集合中的元素。使用TreeSet和Tree Map,就更简单了——想要它们会自动排序必须实现Comparable接口的元素。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Beispielcodes der Java Comparable-Schnittstelle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn