it-swarm.com.de

So vergleichen Sie Objekte anhand mehrerer Felder

Angenommen, Sie haben einige Objekte mit mehreren Feldern, die miteinander verglichen werden können:

public class Person {

    private String firstName;
    private String lastName;
    private String age;

    /* Constructors */

    /* Methods */

}

Wenn Sie also in diesem Beispiel fragen, ob:

a.compareTo(b) > 0

sie fragen sich vielleicht, ob der Nachname von a vor b steht oder ob a älter als b ist usw.

Was ist der sauberste Weg, um einen mehrfachen Vergleich zwischen diesen Arten von Objekten zu ermöglichen, ohne unnötigen Durcheinander oder zusätzlichen Aufwand zu verursachen?

  • Die Java.lang.Comparable-Schnittstelle ermöglicht den Vergleich nur durch ein Feld
  • Das Hinzufügen zahlreicher Vergleichsmethoden (z. B. compareByFirstName(), compareByAge() usw.) ist meiner Meinung nach unübersichtlich.

Was ist also der beste Weg, um dies zu tun?

183
Yuval Adam

Sie können eine Comparator implementieren, die zwei Person-Objekte vergleicht, und Sie können beliebig viele Felder untersuchen. Sie können eine Variable in Ihren Vergleicher einfügen, die angibt, mit welchem ​​Feld verglichen werden soll, obwohl es wahrscheinlich einfacher wäre, mehrere Vergleicher zu schreiben.

69
Elie

Mit Java 8: 

Comparator.comparing((Person p)->p.firstName)
          .thenComparing(p->p.lastName)
          .thenComparingInt(p->p.age);

Wenn Sie über Zugriffsmethoden verfügen:

Comparator.comparing(Person::getFirstName)
          .thenComparing(Person::getLastName)
          .thenComparingInt(Person::getAge);

Wenn eine Klasse Comparable implementiert, kann ein solcher Komparator in der compareTo-Methode verwendet werden:

@Override
public int compareTo(Person o){
    return Comparator.comparing(Person::getFirstName)
              .thenComparing(Person::getLastName)
              .thenComparingInt(Person::getAge)
              .compare(this, o);
}
283
Display Name

Sie sollten Comparable <Person> implementieren. Angenommen, alle Felder werden nicht der Einfachheit halber nicht null sein, das Alter ist ein int und die Rangfolge des Vergleichs ist das erste, letzte, Alter. Die compareTo-Methode ist recht einfach:

public int compareTo(Person other) {
    int i = firstName.compareTo(other.firstName);
    if (i != 0) return i;

    i = lastName.compareTo(other.lastName);
    if (i != 0) return i;

    return Integer.compare(age, other.age);
}
144
Steve Kuo

(aus Haus des Codes )

Unordentlich und verschlungen: Sortierung von Hand

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        int sizeCmp = p1.size.compareTo(p2.size);  
        if (sizeCmp != 0) {  
            return sizeCmp;  
        }  
        int nrOfToppingsCmp = p1.nrOfToppings.compareTo(p2.nrOfToppings);  
        if (nrOfToppingsCmp != 0) {  
            return nrOfToppingsCmp;  
        }  
        return p1.name.compareTo(p2.name);  
    }  
});  

Dies erfordert viel Schreibarbeit, Wartung und ist fehleranfällig.

Der reflektierende Weg: Sortieren mit BeanComparator

ComparatorChain chain = new ComparatorChain(Arrays.asList(
   new BeanComparator("size"), 
   new BeanComparator("nrOfToppings"), 
   new BeanComparator("name")));

Collections.sort(pizzas, chain);  

Natürlich ist dies prägnanter, aber noch fehleranfälliger, da Sie den direkten Bezug zu den Feldern verlieren, indem Sie stattdessen Strings verwenden. Wenn nun ein Feld umbenannt wird, meldet der Compiler nicht einmal ein Problem. Da diese Lösung Reflexion verwendet, ist die Sortierung außerdem viel langsamer.

Anreise: Sortieren mit der Vergleichskette von Google Guava

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        return ComparisonChain.start().compare(p1.size, p2.size).compare(p1.nrOfToppings, p2.nrOfToppings).compare(p1.name, p2.name).result();  
        // or in case the fields can be null:  
        /* 
        return ComparisonChain.start() 
           .compare(p1.size, p2.size, Ordering.natural().nullsLast()) 
           .compare(p1.nrOfToppings, p2.nrOfToppings, Ordering.natural().nullsLast()) 
           .compare(p1.name, p2.name, Ordering.natural().nullsLast()) 
           .result(); 
        */  
    }  
});  

Dies ist viel besser, erfordert jedoch für den häufigsten Anwendungsfall einen Code für die Heizkesselplatte: Nullwerte sollten standardmäßig niedriger bewertet werden. Für Nullfelder müssen Sie eine zusätzliche Direktive für Guava angeben, was in diesem Fall zu tun ist. Dies ist ein flexibler Mechanismus, wenn Sie bestimmte Dinge tun möchten, häufig jedoch den Standardfall (z. B. 1, a, b, z, null).

Sortieren mit Apache Commons CompareToBuilder

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        return new CompareToBuilder().append(p1.size, p2.size).append(p1.nrOfToppings, p2.nrOfToppings).append(p1.name, p2.name).toComparison();  
    }  
});  

Wie die Vergleichskette von Guava kann diese Bibliotheksklasse einfach in mehrere Felder sortiert werden, definiert jedoch auch das Standardverhalten für Nullwerte (dh 1, a, b, z, null). Sie können jedoch auch nichts anderes angeben, es sei denn, Sie stellen einen eigenen Comparator zur Verfügung.

Somit

Letztendlich kommt es auf Geschmack und die Notwendigkeit von Flexibilität (Guava´s ComparisonChain) vs. prägnanten Code (Apache CompareToBuilder) an.

Bonusmethode

Ich habe eine Nice-Lösung gefunden, die mehrere Komparatoren nach Priorität in CodeReview in einer MultiComparator - kombiniert:

class MultiComparator<T> implements Comparator<T> {
    private final List<Comparator<T>> comparators;

    public MultiComparator(List<Comparator<? super T>> comparators) {
        this.comparators = comparators;
    }

    public MultiComparator(Comparator<? super T>... comparators) {
        this(Arrays.asList(comparators));
    }

    public int compare(T o1, T o2) {
        for (Comparator<T> c : comparators) {
            int result = c.compare(o1, o2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }

    public static <T> void sort(List<T> list, Comparator<? super T>... comparators) {
        Collections.sort(list, new MultiComparator<T>(comparators));
    }
}

Natürlich hat Apache Commons Collections bereits einen Nutzen dafür:

ComparatorUtils.chainedComparator (comparatorCollection)

Collections.sort(list, ComparatorUtils.chainedComparator(comparators));
55
Benny Bottema

@Patrick Wenn Sie mehr als ein Feld nacheinander sortieren möchten, versuchen Sie ComparatorChain

Ein ComparatorChain ist ein Komparator, der einen oder mehrere Komparatoren nacheinander umschließt. Der ComparatorChain ruft jeden Comparator der Reihe nach auf, bis entweder 1) ein einzelner Comparator ein Ergebnis ungleich Null zurückgibt (und dieses Ergebnis dann zurückgegeben wird) oder 2) die ComparatorChain erschöpft ist (und Null zurückgegeben wird). Diese Art der Sortierung ähnelt der Sortierung in SQL mit mehreren Spalten. Diese Klasse ermöglicht es Java-Klassen, dieses Verhalten beim Sortieren einer Liste zu emulieren.

Um die SQL-artige Sortierung weiter zu erleichtern, kann die Reihenfolge eines einzelnen Comparators in der Liste umgekehrt werden.

Das Aufrufen einer Methode, die neue Comparators hinzufügt oder die Sortierung aufsteigend/absteigend ändert, nachdem Compare (Object, Object) aufgerufen wurde, führt zu einer UnsupportedOperationException. Achten Sie jedoch darauf, die zugrunde liegende Liste der Vergleicher oder das BitSet, das die Sortierreihenfolge definiert, nicht zu ändern.

Instanzen von ComparatorChain werden nicht synchronisiert. Die Klasse ist zur Konstruktionszeit nicht Thread-sicher, aber es ist Thread-sicher, mehrere Vergleiche durchzuführen, nachdem alle Setup-Vorgänge abgeschlossen sind.

21
Nigel_V_Thomas

Eine andere Option, die Sie immer in Betracht ziehen können, ist Apache Commons. Es bietet viele Möglichkeiten.

import org.Apache.commons.lang3.builder.CompareToBuilder;

Ex:

public int compare(Person a, Person b){

   return new CompareToBuilder()
     .append(a.getName(), b.getName())
     .append(a.getAddress(), b.getAddress())
     .toComparison();
}
18
Xeroiris

Sie können sich auch Enum ansehen, das Comparator implementiert.

http://tobega.blogspot.com/2008/05/beautiful-enums.html

z.B.

Collections.sort(myChildren, Child.Order.ByAge.descending());
11
Boune

Für diejenigen, die die Java 8-Streaming-API verwenden können, gibt es einen besseren Ansatz, der hier gut dokumentiert ist: Lambdas und Sortierung

Ich habe nach dem Äquivalent des C # LINQ gesucht:

.ThenBy(...)

Ich habe den Mechanismus in Java 8 auf dem Comparator gefunden:

.thenComparing(...)

Hier ist der Ausschnitt, der den Algorithmus demonstriert.

    Comparator<Person> comparator = Comparator.comparing(person -> person.name);
    comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));

Schauen Sie sich den Link oben an, um einen genaueren Weg und eine Erklärung darüber zu finden, wie die Typeninferenz von Java die Definition im Vergleich zu LINQ etwas unübersichtlicher macht.

Hier ist der vollständige Unit-Test als Referenz:

@Test
public void testChainedSorting()
{
    // Create the collection of people:
    ArrayList<Person> people = new ArrayList<>();
    people.add(new Person("Dan", 4));
    people.add(new Person("Andi", 2));
    people.add(new Person("Bob", 42));
    people.add(new Person("Debby", 3));
    people.add(new Person("Bob", 72));
    people.add(new Person("Barry", 20));
    people.add(new Person("Cathy", 40));
    people.add(new Person("Bob", 40));
    people.add(new Person("Barry", 50));

    // Define chained comparators:
    // Great article explaining this and how to make it even neater:
    // http://blog.jooq.org/2014/01/31/Java-8-friday-goodies-lambdas-and-sorting/
    Comparator<Person> comparator = Comparator.comparing(person -> person.name);
    comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));

    // Sort the stream:
    Stream<Person> personStream = people.stream().sorted(comparator);

    // Make sure that the output is as expected:
    List<Person> sortedPeople = personStream.collect(Collectors.toList());
    Assert.assertEquals("Andi",  sortedPeople.get(0).name); Assert.assertEquals(2,  sortedPeople.get(0).age);
    Assert.assertEquals("Barry", sortedPeople.get(1).name); Assert.assertEquals(20, sortedPeople.get(1).age);
    Assert.assertEquals("Barry", sortedPeople.get(2).name); Assert.assertEquals(50, sortedPeople.get(2).age);
    Assert.assertEquals("Bob",   sortedPeople.get(3).name); Assert.assertEquals(40, sortedPeople.get(3).age);
    Assert.assertEquals("Bob",   sortedPeople.get(4).name); Assert.assertEquals(42, sortedPeople.get(4).age);
    Assert.assertEquals("Bob",   sortedPeople.get(5).name); Assert.assertEquals(72, sortedPeople.get(5).age);
    Assert.assertEquals("Cathy", sortedPeople.get(6).name); Assert.assertEquals(40, sortedPeople.get(6).age);
    Assert.assertEquals("Dan",   sortedPeople.get(7).name); Assert.assertEquals(4,  sortedPeople.get(7).age);
    Assert.assertEquals("Debby", sortedPeople.get(8).name); Assert.assertEquals(3,  sortedPeople.get(8).age);
    // Andi     : 2
    // Barry    : 20
    // Barry    : 50
    // Bob      : 40
    // Bob      : 42
    // Bob      : 72
    // Cathy    : 40
    // Dan      : 4
    // Debby    : 3
}

/**
 * A person in our system.
 */
public static class Person
{
    /**
     * Creates a new person.
     * @param name The name of the person.
     * @param age The age of the person.
     */
    public Person(String name, int age)
    {
        this.age = age;
        this.name = name;
    }

    /**
     * The name of the person.
     */
    public String name;

    /**
     * The age of the person.
     */
    public int age;

    @Override
    public String toString()
    {
        if (name == null) return super.toString();
        else return String.format("%s : %d", this.name, this.age);
    }
}
7
Luke Machowski
import com.google.common.collect.ComparisonChain;

/**
 * @author radler
 * Class Description ...
 */
public class Attribute implements Comparable<Attribute> {

    private String type;
    private String value;

    public String getType() { return type; }
    public void setType(String type) { this.type = type; }

    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }

    @Override
    public String toString() {
        return "Attribute [type=" + type + ", value=" + value + "]";
    }

    @Override
    public int compareTo(Attribute that) {
        return ComparisonChain.start()
            .compare(this.type, that.type)
            .compare(this.value, that.value)
            .result();
    }

}
6
Ran Adler

Eine Comparator manuell für einen solchen Anwendungsfall zu schreiben, ist eine schreckliche Lösung IMO. Solche Ad-hoc-Ansätze haben viele Nachteile: 

  • Keine Wiederverwendung des Codes. Verstößt TROCKEN.
  • Heizplatte.
  • Erhöhte Möglichkeit von Fehlern.

Also, was ist die Lösung?

Zuerst eine Theorie.

Bezeichnen wir den Satz "Typ A unterstützt Vergleich" durch Ord A. (Aus der Programmperspektive können Sie sich Ord A als ein Objekt vorstellen, das Logik enthält, um zwei As zu vergleichen. Ja, genau wie Comparator.) 

Wenn nun Ord A und Ord B, sollte ihr zusammengesetzter (A, B) auch den Vergleich unterstützen. d.h. Ord (A, B). Wenn Ord A, Ord B und Ord C, dann Ord (A, B, C)

Wir können dieses Argument beliebig ausdehnen und sagen:

Ord A, Ord B, Ord C, ..., Ord ZOrd (A, B, C, .., Z)

Nennen wir diese Aussage 1.

Der Vergleich der Composites funktioniert genau so, wie Sie es in Ihrer Frage beschrieben haben: Der erste Vergleich wird zuerst versucht, dann der nächste, dann der nächste und so weiter.

Das ist der erste Teil unserer Lösung. Nun der zweite Teil.

Wenn Sie diesen Ord A kennen und wissen, wie Sie B in A umwandeln (diese Umwandlungsfunktion f aufrufen), können Sie auch Ord B verwenden. Wie? Nun, wenn die beiden B-Instanzen verglichen werden sollen, transformieren Sie sie zuerst mit A in f und wenden dann Ord A an.

Hier bilden wir die Transformation B → A in Ord A → Ord B ab. Dies wird als kontravariantes Mapping (oder comap) bezeichnet.

Ord A, (B → A)comap Ord B

Nennen wir diese Aussage 2.


Nun wenden wir das auf Ihr Beispiel an. 

Sie haben einen Datentyp mit dem Namen Person, der drei Felder des Typs String umfasst. 

  • Wir wissen, dass Ord String. Mit Anweisung 1 Ord (String, String, String)

  • Wir können problemlos eine Funktion von Person bis (String, String, String) schreiben. (Gib einfach die drei Felder zurück.) Da wir Ord (String, String, String) und Person → (String, String, String) durch Anweisung 2 kennen, können wir comap verwenden, um Ord Person zu erhalten. 

QED.


Wie setze ich all diese Konzepte um?

Die gute Nachricht ist, dass Sie nicht müssen. Es gibt bereits eine Bibliothek , die alle in diesem Beitrag beschriebenen Ideen umsetzt. (Wenn Sie neugierig sind, wie diese implementiert werden, können Sie unter die Haube schauen .)

So sieht der Code aus:

Ord<Person> personOrd = 
 p3Ord(stringOrd, stringOrd, stringOrd).comap(
   new F<Person, P3<String, String, String>>() {
     public P3<String, String, String> f(Person x) {
       return p(x.getFirstName(), x.getLastname(), x.getAge());
     }
   }
 );

Erklärung:

  • stringOrd ist ein Objekt vom Typ Ord<String>. Dies entspricht unserem ursprünglichen Vorschlag "Vergleiche unterstützen".
  • p3Ord ist eine Methode, die Ord<A>, Ord<B>, Ord<C> verwendet und Ord<P3<A, B, C>> zurückgibt. Dies entspricht der Anweisung 1. ( P3 steht für ein Produkt mit drei Elementen. Produkt ist ein algebraischer Begriff für Composites.)
  • comap entspricht gut, comap.
  • F<A, B> repräsentiert eine Transformationsfunktion A → B.
  • p ist eine werkseitige Methode zum Erstellen von Produkten.
  • Der gesamte Ausdruck entspricht der Aussage 2.

Hoffentlich hilft das.

6
missingfaktor

Anstelle von Vergleichsmethoden möchten Sie vielleicht einfach mehrere Arten von "Comparator" -Unterklassen in der Person-Klasse definieren. Auf diese Weise können Sie sie in standardisierte Collections-Sortiermethoden übergeben.

4
Marc Novakowski

Ich denke, es wäre verwirrender, wenn Ihr Vergleichsalgorithmus "clever" wäre. Ich würde auf die zahlreichen von Ihnen vorgeschlagenen Vergleichsmethoden zurückgreifen.

Die einzige Ausnahme für mich wäre Gleichheit. Für Unit-Tests war es für mich nützlich, die .Equals (in .net) zu überschreiben, um festzustellen, ob mehrere Felder zwischen zwei Objekten gleich sind (und nicht, dass die Referenzen gleich sind).

2
Michael Haren

Wenn der Benutzer mehrere Möglichkeiten hat, eine Person zu bestellen, können Sie auch mehrere Comparator s-Einstellungen als Konstanten einrichten. Die meisten Sortiervorgänge und sortierten Sammlungen verwenden einen Vergleicher als Parameter.

2
sblundy

Es ist einfach, zwei Objekte mit der Hashcode-Methode in Java zu vergleichen

public class Sample{

  String a=null;
  String b=null;

  public Sample(){
      a="s";
      b="a";
  }
  public Sample(String a,String b){
      this.a=a;
      this.b=b;
  }
  public static void main(String args[]){
      Sample f=new Sample("b","12");
      Sample s=new Sample("b","12");
      //will return true
      System.out.println((s.a.hashCode()+s.b.hashCode())==(f.a.hashCode()+f.b.hashCode()));

      //will return false
      Sample f=new Sample("b","12");
      Sample s=new Sample("b","13");
      System.out.println((s.a.hashCode()+s.b.hashCode())==(f.a.hashCode()+f.b.hashCode()));

}
1
Exodus
//here threshold,buyRange,targetPercentage are three keys on that i have sorted my arraylist 
final Comparator<BasicDBObject> 

    sortOrder = new Comparator<BasicDBObject>() {
                    public int compare(BasicDBObject e1, BasicDBObject e2) {
                        int threshold = new Double(e1.getDouble("threshold"))
                        .compareTo(new Double(e2.getDouble("threshold")));
                        if (threshold != 0)
                            return threshold;

                        int buyRange = new Double(e1.getDouble("buyRange"))
                        .compareTo(new Double(e2.getDouble("buyRange")));
                        if (buyRange != 0)
                            return buyRange;

                        return (new Double(e1.getDouble("targetPercentage")) < new Double(
                                e2.getDouble("targetPercentage")) ? -1 : (new Double(
                                        e1.getDouble("targetPercentage")) == new Double(
                                                e2.getDouble("targetPercentage")) ? 0 : 1));
                    }
                };
                Collections.sort(objectList, sortOrder);
1
Pradeep Singh
//Following is the example in jdk 1.8
package com;
import Java.util.ArrayList;
import Java.util.Comparator;
import Java.util.List;

class User {
    private String firstName;
    private String lastName;
    private Integer age;

    public Integer getAge() {
        return age;
    }

    public User setAge(Integer age) {
        this.age = age;
        return this;
    }

    public String getFirstName() {
        return firstName;
    }

    public User setFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public String getLastName() {
        return lastName;
    }

    public User setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

}

public class MultiFieldsComparision {

    public static void main(String[] args) {
        List<User> users = new ArrayList<User>();

        User u1 = new User().setFirstName("Pawan").setLastName("Singh").setAge(38);
        User u2 = new User().setFirstName("Pawan").setLastName("Payal").setAge(37);
        User u3 = new User().setFirstName("Anuj").setLastName("Kumar").setAge(60);
        User u4 = new User().setFirstName("Anuj").setLastName("Kumar").setAge(43);
        User u5 = new User().setFirstName("Pawan").setLastName("Chamoli").setAge(44);
        User u6 = new User().setFirstName("Pawan").setLastName("Singh").setAge(5);

        users.add(u1);
        users.add(u2);
        users.add(u3);
        users.add(u4);
        users.add(u5);
        users.add(u6);

        System.out.println("****** Before Sorting ******");

        users.forEach(user -> {
            System.out.println(user.getFirstName() + " , " + user.getLastName() + " , " + user.getAge());
        });

        System.out.println("****** Aftre Sorting ******");

        users.sort(
                Comparator.comparing(User::getFirstName).thenComparing(User::getLastName).thenComparing(User::getAge));

        users.forEach(user -> {
            System.out.println(user.getFirstName() + " , " + user.getLastName() + " , " + user.getAge());
        });

    }

}
0
Pawan

Normalerweise überschreibe ich meine compareTo()-Methode, wenn ich die Multilevel-Sortierung durchführen muss.

public int compareTo(Song o) {
    // TODO Auto-generated method stub
    int comp1 = 10000000*(movie.compareTo(o.movie))+1000*(artist.compareTo(o.artist))+songLength;
    int comp2 = 10000000*(o.movie.compareTo(movie))+1000*(o.artist.compareTo(artist))+o.songLength;
    return comp1-comp2;
} 

Hier wird zuerst der Filmename vor dem Künstler und zuletzt dem SongLength bevorzugt. Sie müssen nur sicherstellen, dass diese Multiplikatoren so weit entfernt sind, dass sie die Grenzen des anderen nicht überschreiten. 

0
jayanth

Ausgehend von Steves Antwort kann der ternäre Operator verwendet werden:

public int compareTo(Person other) {
    int f = firstName.compareTo(other.firstName);
    int l = lastName.compareTo(other.lastName);
    return f != 0 ? f : l != 0 ? l : Integer.compare(age, other.age);
}
0
Gerold Broser

Wenn Sie die Comparable - Schnittstelle implementieren, sollten Sie eine einfache Eigenschaft zur Bestellung auswählen. Dies wird als natürliche Ordnung bezeichnet. Betrachten Sie es als Standard. Es wird immer verwendet, wenn kein spezieller Vergleicher geliefert wird. Normalerweise ist dies der Name, aber in Ihrem Anwendungsfall ist möglicherweise etwas anderes erforderlich. Sie können beliebig viele andere Komparatoren verwenden, die Sie für verschiedene Sammlungen-APIs bereitstellen können, um die natürliche Reihenfolge zu überschreiben.

Beachten Sie außerdem, dass in der Regel a.compareTo (b) == 0 und dann a.equals (b) == true ist. Es ist in Ordnung, wenn nicht, aber es gibt Nebenwirkungen, die Sie beachten sollten. Sehen Sie sich die hervorragenden Javadocs auf der Comparable-Oberfläche an und Sie finden viele Informationen dazu.

0
Mark Renouf

Folgender Blog mit gutem Verkettungsbeispiel 

http://www.codejava.net/Java-core/collections/sorting-a-list-by-multiple-attributes-example

import Java.util.Arrays;
import Java.util.Comparator;
import Java.util.List;

/**
 * This is a chained comparator that is used to sort a list by multiple
 * attributes by chaining a sequence of comparators of individual fields
 * together.
 *
 */
public class EmployeeChainedComparator implements Comparator<Employee> {

    private List<Comparator<Employee>> listComparators;

    @SafeVarargs
    public EmployeeChainedComparator(Comparator<Employee>... comparators) {
        this.listComparators = Arrays.asList(comparators);
    }

    @Override
    public int compare(Employee emp1, Employee emp2) {
        for (Comparator<Employee> comparator : listComparators) {
            int result = comparator.compare(emp1, emp2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }
}

Vergleicher aufrufen:

Collections.sort(listEmployees, new EmployeeChainedComparator(
                new EmployeeJobTitleComparator(),
                new EmployeeAgeComparator(),
                new EmployeeSalaryComparator())
        );
0
vaquar khan