Vergleich von Objekten anhand variierender Kriterien

Raphalon

Aktives Mitglied
Hallo,

in einem Programm möchte ich File-Objekte miteinander vergleichen, die sich in einer Collection, z.B. HashSet<File> befinden. Der Anwender kann zuvor auswählen, nach welchen Kriterien verglichen werden soll, also etwa
- lastModified und size oder
- nur size oder
- lastModified, size und canRead
- usw.

Um die File-Objekte miteinander vergleichen zu können, überschreibe ich equals(). Dabei möchte ich dann nur diejenigen Kriterien für den Vergleich verwenden, die der User zuvor selektiert hat. Wie aber kann ich alle möglichen Kombinationen von Vergleichskriterien berücksichtigen? Bei nur zwei Kriterien könnte man vielleicht noch mit if-else-Blöcken die Variationen berücksichtigen. Doch wie geht das bei z.B. 8-10 möglichen Kriterien? Wie kann ich das umsetzen? Gibt es da irgendein Design-Pattern?

Viele Grüße,

Raphalon
 
equals zu überschreiben macht da nicht viel Sinn, und kann übel nach hinten losgehen wenn man's falsch macht (equals muss bestimmte Bedingungen erfüllen).

Kannst mal schauen, was bei http://www.java-forum.org/allgemeines/39510-arrays-listen-sortieren.html zu "Comparatoren" steht. Im speziellen würde man für Files dann einen Comparator erstellen, der nach Datum sortiert, und einen, der nach Größe sortiert, und die dann entsprechend verwenden. Praktischerweise könnte man auch einen "CompoundComparator" erstellen, der intern eine Liste von Comparatoren (also Sortierkriterien) hat und die beim Vergleich der Reihe nach abklappert.
 
Danke für den Tip. Die Verwendung eines Comparator wäre eine Idee. Mir ist aber nicht klar, wie genau das ingesamt geht. Ich hätte z.B. eine Klasse, die von File abgeleitet ist und die das Interface (Comparable oder Comparator) implementiert. Dabei würde ich dann z.B. das Kriterium size verwenden. Sollte ich jetzt das Interface mehrfach implementieren, um auch Comparators für die anderen Kriterien zu haben? Wie geht das? Und wie würde ich diese dann kombinieren? Wenn man wiederum nur eine Implementierung verwendet, dann stellt sich wieder die Frage, wie man den unterschiedlichen Kombinationen der Kriterien Rechnung trägt, also alle Variationen erlaubt.

Ich kann mir also unter "die dann entsprechend verwenden" und "der Reihe nach abklappert" noch nichts konkretes vorstellen. Könntest Du da noch Hinweise geben?
 
Nein, der wichtigste Vorteil beim Comparator ist eben, dass man NICHT von der Klasse erben muss. (Von File zu erben ist sehr heikel - das ist eine vergleichsweise "Betriebssystemnahe" Klasse, der sollte man nicht ins Handwerk pfuschen...)

Comparator ist ein Interface, das man NUR implementiert, um eben eine Klasse zu haben, die Vergleiche durchführen kann. Ein Beispiel könnte sein
Java:
class FileBySizeComparator implements Comparator<File>
{
    public int compare(File f0, File f1)
    {
        if (f0 ist größer als f1) return -1;
        if (f1 ist größer als f0) return  1;
        return 0;
    }
}
Und ähnlich eben einen "FileByDateComparator" oder so..


Dann kann man z.B. eine Liste von File-Objekten so sortieren:
Code:
List<File> files = ...
Collections.sort(files, new FileBySizeComparator());

Um zwei Comparatoren zu kombinieren kann man dann sowas machen wie
Java:
class CompoundComparator implements Comparator<File>
{
    private Comparator<File> c0;
    private Comparator<File> c1;

    public CompoundComparator(Comparator<File> c0, Comparator<File> c1)
    {
        this.c0 = c0;
        this.c1 = c1;
    }

    public int compare(File f0, File f1)
    {
        int result = c0.compare(f0, f1;
        if (result != 0) return result;
        result = c1.compare(f0, f1);
        return result;
    }
}
(Könnte man mit einer Liste und Generics noch allgemeiner machen)


Wenn man dann sowas macht wie
Code:
List<File> files = ...
Comparator<File> c0 = new FileBySizeComparator();
Comparator<File> c1 = new FileByDateComparator();
Comparator<File> c = new CompoundComparator(c0, c1);
Collections.sort(files, c);

Dann werden die Dateien nach der Größe sortiert, und wenn die Größe gleich ist, wird nach dem Datum sortiert (Stichwort "Lexikographische Sortierung")
 
Mit dem Comparator kann man eine Collection sortieren (und _innerhalb_ dieser Collection vergleichen). Kann ich das aber auch verwenden, wenn ich zwei Collections habe? In beiden Collections sind File-Objekte. Und nun soll für jedes File-Objekt der einen Collection herausgefunden werden, ob es sie auch in der anderen Collection gibt. Das wäre sozusagen das Delta. Vermutlich habe ich meine ursprüngliche Frage nicht klar genug formuliert, doch darum geht es mir.
 
Vermutlich habe ich meine ursprüngliche Frage nicht klar genug formuliert, doch darum geht es mir.

Richtig. Davon stand in der ursprünglichen Frage kein Wort :noe:

Code:
Collection<File> c0 = ...
Collection<File> c1 = ...
Comparator<File> comparator = ...
for (File f0 : c0)
{
    for (File f1 : c1)
    {
        int value = comparator.compare(c0, c1);
        if (value == 0)
        {
            System.out.println("Sowas wie "+f0+" gibts auch in "+c1);
        }
    }
}
 

Zurück
Oben