Comparable & Comparator

b1zarRe

Bekanntes Mitglied
Hi,

ja ich habe nach dem Thema hier schon gesucht und was gefunden, doch
leider erklärt mir das noch nicht meine Frage, also:

Mit Comparable kann ich ja nun N Instanzen einer Klasse sortieren.(indem
ich die compareTo(Object o) korrekt überschreibe)... alles klar.

Aber was ist der Vorteil von Comparator?
Ist das lediglich, dass man damit verschiedenstartige Sortierungen vornehmen kann,
zb.: bei einer Klasse Student einen Comparator fürs Namen Sortieren und einen
fürs Matrikelnr studieren?

Ist das der einzige Vorteil?

ODER: Lassen sich mit einem Comparator auch zwei gaanz verschiedene Typen vergleichen.
zb.: eine Instanz der Klasse Student und eine Instanz der Klasse Artikel...? ist das machbar...?
ja, ich habe es ausprobiert und leider kommt bei mir immer die Fehlermeldung
das ich Klasse A nicht zu Klasse B casten kann, obwohl ich das Casting im Comparator
richtig vorgenommen habe....?

Das ganze Vorhaben habe ich mit 2 verschiedenen Objekten versucht und in eine (genericfreie)
ArrayList gepackt und dann mit Collections.sort(arraylist, new MeinComparator());
probiert..?

Mache ich was falsch, oder ist das dafür nicht vorgesehen?
 
G

Gast2

Gast
Bei
Code:
Comparable
steckt die Logik wie zwei Intanzen soritert werden direkt in der Klasse. Beim
Code:
Comparator
wird diese Logik ausgelagert, beide Varianten können Sinn machen.

ODER: Lassen sich mit einem Comparator auch zwei gaanz verschiedene Typen vergleichen.
zb.: eine Instanz der Klasse Student und eine Instanz der Klasse Artikel...? ist das machbar...?
Nein, das kann nicht funktionieren. Comparator hat nur einen generischen Parameter. Du kannst also nur Ts mit Ts vergleichen.
 

Marco13

Top Contributor
Technisch möglich ist es. Man KANN in einen Comparator natürlich sowas schreiben wie
Java:
String name0 = null;
String name1 = null;
if (object0 instanceof Article) name0 = ((Article)object0).getArticleName();
if (object0 instanceof Person) name0 = ((Person)object0).getPersonName();
if (object1 instanceof Article) name1 = ((Article)object1).getArticleName();
if (object1 instanceof Person) name1 = ((Person)object1).getPersonName();
return name0.compareTo(name1);

Für SINN ist eine Programmiersprache zum Glück nicht zuständig :D

Für "Comparable" ist explizit gefordert, dass sie (nur?) mutually comparable sein muss.
 

b1zarRe

Bekanntes Mitglied
Leider ist mir der Unterschied noch nicht wirklich klar..., und jetzt auch im Lesen des "Handbuch der Java Programmierens" zitiere ich: (Seite 204) "(...) Auch Objekte unterschiedlicher Klassen können problemlos miteinander verglichen werden, sofern compareTo dazu in der Lage ist. So ist es leicht vorstellbar, dass sowohl Autos als auch Fussballplätze und Papierblätter(und eventuell noch Äpfel und Birnen) auf der basis ihrer Grundfläche miteinander verglichen werden, denn diese Maßzahl hat für alle beteiligten Klassen eine Bedeutung".

Nun deshalb nochmal die Frage für dumme wie mich :D

1. Comparable -> Benutzen um A) zwei Objekte EINER Klasse zu vergleichen undOder B) Objekte vergleichen zwischen diversen Klassen && A) ?
2. Comparator -> Sinnvoll zum Erzeugen von diversen eignen Comparator Klasse, welche je nach Zweck eingesetzt werden können... zb. einen für Sortierung nach Preis, einen für Artikelnr. etc. -> Nur für Instanzen einer Klasse oder auch für beliebige Klassen???
 

Marco13

Top Contributor
Etwas mehr Kontext wäre da hilfreich. So, wie das dort beschrieben ist, könnte man es im schlimmsten Fall so verstehen, wie im oben geposteten Codeschnipsel, aber das macht natürlich keinen Sinn!

Vermutlich bezieht es sich nur darauf, dass man Objekte verschiedener Klassen vergleichen kann, wenn sie eine gemeinsame Basisklasse (bzw. ein gemeinsames Interface) haben, das das Vergleichskriterium festlegt. Im Beispiel oben könnte es z.B. sowas geben wie
Java:
interface NameOwner 
{
    String getName();
}

class Person implements NameOwner, Comparable<NameOwner>
{
    @Override
    public int compareTo(NameOwner o)
    {
        return 0;
    }

    @Override
    public String getName()
    {
        return null;
    }
    
}

class Artikel implements NameOwner, Comparable<NameOwner>
{
    @Override
    public int compareTo(NameOwner o)
    {
        return 0;
    }

    @Override
    public String getName()
    {
        return null;
    }
    
}

class Main
{
    public static void main(String[] args)
    {
        Person person = new Person();
        Artikel artikel = new Artikel();
        
        artikel.compareTo(person); // Geht
    }
}

Analog dazu könnte man auch einen Comparator erstellen, der zwei "NameOwner"-Objekte vergleicht.

Der Unterschied zwischen Comparable und Comparator ist eigentlich in erster Linie die Frage, WO die Vergleichbarkeit definiert wird: IN der Klasse oder außerhalb. Comparable verwendet man i.a. dann, wenn es eine inhärente Ordnung auf den Objekten gibt (Integer, String...).

Es gibt aber IMHO einen wichtigen Grund, im allgemeinen (für den öffentlichen Teil der API) Comparatoren zu verwenden: Wenn man Comparable-Objekte hat, kann man auf triviale Weise einen Comparator erstellen, der diese Comparable-Objekte vergleicht. Umgekehrt geht das nicht: Wenn eine Methode ewartet, dass man ihr Comparable-Objekte gibt (damit sie sie sortieren kann), aber die Objekte, die man hat, SIND einfach nicht Comparable, dann hat man verloren, und muss mit irgendwelchen Wrapper-Klassen rummurksen oder so...

Ich persönlich verwende Comparable sehr selten, und eigentlich nie in einer öffentlichen API, sondern wenn überhaupt dann in irgendwelchen (package) privaten Klassen, die nur intern nach einem festen Kriterium sortiert werden müssen.
 

Ark

Top Contributor
Comparable verwendet man i.a. dann, wenn es eine inhärente Ordnung auf den Objekten gibt (Integer, String...).
Bzw. wenn es eine strukturverträgliche Totalordnung gibt, siehe geordneter Körper.

Es gibt aber IMHO einen wichtigen Grund, im allgemeinen (für den öffentlichen Teil der API) Comparatoren zu verwenden: Wenn man Comparable-Objekte hat, kann man auf triviale Weise einen Comparator erstellen, der diese Comparable-Objekte vergleicht. Umgekehrt geht das nicht: Wenn eine Methode ewartet, dass man ihr Comparable-Objekte gibt (damit sie sie sortieren kann), aber die Objekte, die man hat, SIND einfach nicht Comparable, dann hat man verloren, und muss mit irgendwelchen Wrapper-Klassen rummurksen oder so...
Ja, ich finde die Java-Lösung mit Comparable und Comparator auch Murks. Es wäre besser, wenn es dort so gemacht worden wäre wie mit Iterable und Iterator. Dann wäre Comparable (mit einer Methode comparator()) nur eine Garantie, dass es einen Comparator gibt; und die eigentlichen Implementierungen wären immer nur in Comparator-Klassen zu finden.

Mit equals() ist es imo noch schlimmer, man kann sich ja mehrere verschiedene Äquivalenzrelationen für dieselbe OO-Klasse von Objekten vorstellen.

… und gleich sind wir bei funktionaler Programmierung. :D

Ark
 

Marco13

Top Contributor
Bzw. wenn es eine strukturverträgliche Totalordnung gibt, siehe geordneter Körper.

Auch diese würde man ggf. ändern können, wie du ja selbst sagst (und als ich das und den darauf folgenden Abschnitt gelesen habe, dachte ich auch gleich, das Beispiel anbringen zu können, dass man selbst Gleichheit (equals) gerne "von außen" definieren können wollte, aber dann hast du es schon selbst geschrieben :D )

Es wäre besser, wenn es dort so gemacht worden wäre wie mit Iterable und Iterator. Dann wäre Comparable (mit einer Methode comparator()) nur eine Garantie, dass es einen Comparator gibt; und die eigentlichen Implementierungen wären immer nur in Comparator-Klassen zu finden.

Im Moment verstehe ich (vielleicht wegen Schlaf- aka Koffeinmagel) nicht, wo da der Vorteil wäre: Man würde doch wieder das Kriterium an die Klasse selbst binden :bahnhof: Am "flexibelsten" im oben angedeuteten Sinne wäre eigentlich, wenn es "Comparable" gar nicht gäbe, aber natürlich wäre das oft unpraktisch, und für alles "praktischere" stößt man schnell an sprachliche Grenzen...
 

Ark

Top Contributor
Im Moment verstehe ich (vielleicht wegen Schlaf- aka Koffeinmagel) nicht, wo da der Vorteil wäre: Man würde doch wieder das Kriterium an die Klasse selbst binden :bahnhof: Am "flexibelsten" im oben angedeuteten Sinne wäre eigentlich, wenn es "Comparable" gar nicht gäbe, aber natürlich wäre das oft unpraktisch, und für alles "praktischere" stößt man schnell an sprachliche Grenzen...
Ja, das Problem ist wohl, dass man in Interfaces keine statischen Methoden deklarieren kann. Dann könnte man nämlich so was schreiben wie hier:
Java:
	public ComparatorBeispiel(Collection<? extends E> collection){
		this(collection, ((Comparable) E).comparator());
	}
	
	public ComparatorBeispiel(Collection<? extends E> collection, Comparator<? super E> comparator){
		// usw.
		this.comparator = comparator;
		// usf.
	}
(Mit dem Generics-Kram bin ich mir nicht so sicher, ich hoffe aber, das klar ist, was gemeint ist.)

Dass das wiederum nicht geht, hat sicherlich irgendeine Bewandtnis, die mir gerade nicht einfallen mag (wahrscheinlich irgendwas mit dem Typsystem, Vererbung etc.). Auf jeden Fall könnte man sich viele Tests der Form [c]if (comparator != null)[/c], wie sie in z.B. TreeMap vorkommen, sparen.

(Es kann natürlich auch sein, dass ich gerade Sachen komplizierte mache, als sie sind. :oops: )

Ark
 
S

SlaterB

Gast
> Dann könnte man nämlich so was schreiben wie hier:

das geht auch jetzt schon wie von Marco13 geschrieben:
ein Comparator, der nur compareTo() der Klasse aufruft, ist schnell geschrieben, kein Aufwand


----

ich finde die Tendenzen hier nicht grundsätzlich gut, mit den gleichen Argumenten kann man auch jede andere
Funktionalität einer Klasse/ eines Interfaces herunterreden, wozu z.B. toString(), wieso nicht separat einen StringCreator?

aber Sortieren ist durchaus ein Spezialfeld, Comparator schon etabliert und wichtig,
und die genannte Alternative, Wrapper um jedes zu sortierende Element, ist schon eine hart Nuss,
durchaus verständlich
 

Marco13

Top Contributor
ich finde die Tendenzen hier nicht grundsätzlich gut, mit den gleichen Argumenten kann man auch jede andere
Funktionalität einer Klasse/ eines Interfaces herunterreden, wozu z.B. toString(), wieso nicht separat einen StringCreator?

Wie Ark schon angedeutet hat geht das in Richtung funktionaler Programmierung (das driftet dann ggf. etwas vom Thema ab, wenn es ausartet kann man es ja abtrennen (und vielleicht mit einem der vielen anderen Threads mergen, in denen genau darüber geredet wurde)).

Aber ich finde das durchaus etwas, was öfter mal "fehlt". Im Moment gibt es sowas wie
[c]someList.contains(element);[/c]
was die Liste durchgeht und überprüft, ob es ein Element gibt, das equals(element) ist. Man muss sich nur vorstellen, wie die Mächtigkeit dieser Funktion explodieren würde, wenn man dort ein "Predicate" übergeben könnte:
Java:
someList.contains(Predicates.equalsTo(element));
someList.contains(Predicates.hasNameLike(somePerson)); // mit Person#getName()
...
Die Vorteile, die so ein Konstrukt hätte, erschließen sich unmittelbar, wenn man einen Blick auf funktionale Programmierung wirft (vgl. auch "Interne Iteration" und "Externe Iteration", wie sie auch hier erwähnt ist: Java Collections API Design FAQ ).

Man könnte jetzt sagen: "Jaja, Gelaber, Java IST nunmal keine funktionale Sprache". Aber es wird wirklich immer wichtiger, fast unumgänglich - und das wurde erfreulicherweise auch erkannt und antizipiert: State of the Collections
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Comparable bzw Comparator Java Basics - Anfänger-Themen 5
M Comparable und Comparator nicht ganz klar Java Basics - Anfänger-Themen 1
S Unterschied Comparable und Comparator Java Basics - Anfänger-Themen 2
H Comparable und Comparator Java Basics - Anfänger-Themen 22
S Comparator / Comparable ? Java Basics - Anfänger-Themen 3
D Frage zu Collection.sort bzw. Comparator u. Comparable Java Basics - Anfänger-Themen 2
B Wann Comparator und wann Comparable Java Basics - Anfänger-Themen 6
J HashSet mit Comparable sortieren Java Basics - Anfänger-Themen 13
J Interface Comparable<T> Java Basics - Anfänger-Themen 10
L Interface & Comparable Java Basics - Anfänger-Themen 15
I Generics und Comparable Java Basics - Anfänger-Themen 14
O Comparable Generic Java Basics - Anfänger-Themen 24
R Quicksort mit Interface Comparable Java Basics - Anfänger-Themen 6
Kornblume Comparable Interface für Objektvergleiche nutzen Java Basics - Anfänger-Themen 15
C Was macht `public class ClassName<T extends Comparable<T>>`? Java Basics - Anfänger-Themen 14
M Generische Liste aus Comparable-Objekten Java Basics - Anfänger-Themen 6
R Interface Eigene Objekte in Listen sortieren mit Interface Comparable Java Basics - Anfänger-Themen 5
K Comparable - Objekte aus Array vergleichen und größtes auswählen Java Basics - Anfänger-Themen 1
Shizmo Frage zu Comparable Java Basics - Anfänger-Themen 4
L LinkedList Comparable < > MEHRFACH implementieren? Java Basics - Anfänger-Themen 3
N Datentypen LocalDate Generic Comparable Java Basics - Anfänger-Themen 2
S Generics und Comparable Interface Java Basics - Anfänger-Themen 5
N Compiler-Fehler Comparable / compareTo implementierung Java Basics - Anfänger-Themen 2
F Comparable mit String Java Basics - Anfänger-Themen 5
F Objekte sortieren mit Comparable Java Basics - Anfänger-Themen 9
R Mehrere Interfaces(Comparable, ...) Java Basics - Anfänger-Themen 2
C Comparable Interface Java Basics - Anfänger-Themen 8
T Interface Interface Comparable Problem... Java Basics - Anfänger-Themen 2
H Interface Comparable Verständnisfrage Java Basics - Anfänger-Themen 6
B Object "Method" in TreeSet, Fehler beim Vergleichen/Comparable Java Basics - Anfänger-Themen 9
pg1337 Interface Comparable-Interface bei HashMap Java Basics - Anfänger-Themen 21
J Probleme mit Comparable, compareTo() Java Basics - Anfänger-Themen 2
A Comparable interface Java Basics - Anfänger-Themen 26
I Interface Comparable für Server-Item-Interface Java Basics - Anfänger-Themen 12
P Comparable und Generics Java Basics - Anfänger-Themen 6
S comparable und equals Java Basics - Anfänger-Themen 7
M Frage zum Interface Comparable Java Basics - Anfänger-Themen 3
S Comparable Java Basics - Anfänger-Themen 4
S instanceof Comparable...geht nicht? Java Basics - Anfänger-Themen 20
M comparable funktion & reverse funktion Java Basics - Anfänger-Themen 8
H Mehrere Comparable Java Basics - Anfänger-Themen 4
D Comparable - Bucketsort / Radixsort? Java Basics - Anfänger-Themen 2
B Mehrere Werte mit Comparable sortieren Java Basics - Anfänger-Themen 14
S String umwandeln in Comparable Java Basics - Anfänger-Themen 6
R Comparable Interface Funktionalität selbst programmieren? Java Basics - Anfänger-Themen 3
A Interface Comparable Java Basics - Anfänger-Themen 2
J Comparable Java Basics - Anfänger-Themen 9
frau-u Wie vergleicht Comparable Java Basics - Anfänger-Themen 2
M Comparable - Bedingung erzwingen Java Basics - Anfänger-Themen 3
N Spezielle frage zum Comparator Java Basics - Anfänger-Themen 6
M Comparator Java Basics - Anfänger-Themen 25
M Comparator Java Basics - Anfänger-Themen 4
berserkerdq2 Wie lege ich ein Attribut comparator an? Java Basics - Anfänger-Themen 13
W Personen sortieren mit Comparator Java Basics - Anfänger-Themen 9
H Comparator Fehlermeldung Java Basics - Anfänger-Themen 5
V Collections ArrayList mit Comparator sortieren Java Basics - Anfänger-Themen 16
B Collections Objektreferenz-ID in der Ausgabe (Comparator Interface) Java Basics - Anfänger-Themen 2
R Methode zwei Sortierkriterien der Klasse Comparator übergeben Java Basics - Anfänger-Themen 4
O Lambda Ausdrücke in einem Comparator Java Basics - Anfänger-Themen 4
A Priority Queue / Comparator Java Basics - Anfänger-Themen 6
I Comparator<T> Interface als Methodenparamter Java Basics - Anfänger-Themen 4
L Binäre Suche mit Comparator Java Basics - Anfänger-Themen 5
J Comparator Java Basics - Anfänger-Themen 21
A Comparator Java Basics - Anfänger-Themen 4
G Interface java.util.Comparator: Wieso muss nur die Methode compare() implementiert werden Java Basics - Anfänger-Themen 2
V Comparator Java Basics - Anfänger-Themen 16
S Integer/Value-Paar in Prio-Queue ohne Comparator Java Basics - Anfänger-Themen 5
C Comparator und private Variablen Java Basics - Anfänger-Themen 7
S Comparator für Generiks Java Basics - Anfänger-Themen 6
Helgon Interface Comparator wird nicht instanziert Java Basics - Anfänger-Themen 3
C Comparator mit Double Werten? Java Basics - Anfänger-Themen 12
E Comparator sortiert falsch... Java Basics - Anfänger-Themen 2
M Comparator Java Basics - Anfänger-Themen 7
B OOP Logikhilfe zum Comparator 2 Java Basics - Anfänger-Themen 12
B OOP Logikhilfe zum Comparator Java Basics - Anfänger-Themen 11
G Comparator Problem Java Basics - Anfänger-Themen 5
X eigener Mergesort auf generischen Typen mit Comparator Java Basics - Anfänger-Themen 6
Z Comparator Verständnisfrage Java Basics - Anfänger-Themen 5
B OOP Comparator - Sortierung "optisch" Darstellen Java Basics - Anfänger-Themen 17
A JTable sortieren mit einem Comparator Java Basics - Anfänger-Themen 2
G Objekte mit dem Attribut title mit Comparator sortieren Java Basics - Anfänger-Themen 5
P unchecked conversion to conform to Comparator Java Basics - Anfänger-Themen 3
G Comparator- methode compare exception werfen Java Basics - Anfänger-Themen 4
B interface Comparator Java Basics - Anfänger-Themen 4
M Hilfe bei der Erstellung der Comparator Klasse Java Basics - Anfänger-Themen 10
M ArrayList sortieren mittels Comparator Java Basics - Anfänger-Themen 10
G Sortieren ohne Comparator? Java Basics - Anfänger-Themen 4
G Comparator Java Basics - Anfänger-Themen 10
S Frage zu Comparator Java Basics - Anfänger-Themen 3
G ArrayList und Comparator Java Basics - Anfänger-Themen 6
M Comparator - Sortierkriterium Java Basics - Anfänger-Themen 11
L Comparator Java Basics - Anfänger-Themen 5
T Problem mit Comparator! Java Basics - Anfänger-Themen 7
C Anstatt Spalte, Zeile mit Comparator sortieren . Java Basics - Anfänger-Themen 5
B Liste sortieren mit Comparator Java Basics - Anfänger-Themen 2
S JTable mit Comparator sortieren, die Frage ist wo? Java Basics - Anfänger-Themen 4
W Comparator Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben