2011-08-19 3 views
6

Se ho la seguente classe:Come utilizzare correttamente il comparatore Java?

public class Employee { 
    private int empId; 
    private String name; 
    private int age; 

    public Employee(int empId, String name, int age) { 
     // set values on attributes 
    } 
    // getters & setters 
} 

Come posso usare il comparatore che confronta in base al nome, quindi l'età, quindi id?

+2

Per coloro downvoting, si prega di aiuto dicendo perché/come la questione merita una downvote a voi. –

+0

Non puoi sovrascrivere il metodo ".equals()" che confronta tutti e tre i valori? ... Spiacenti, mi sono reso conto un po 'più tardi che potresti voler ordinare gli oggetti e quindi il comparatore! – Sap

risposta

8

È necessario implementarlo in modo che ordini per elementi preferiti. Cioè, è necessario confrontare in base al nome, poi se questo confronto è uguale, confrontare per età, ecc Un esempio è riportato di seguito:

public class EmployeeComparator implements Comparator<Employee> { 

    @Override 
    public int compare(Employee e1, Employee e2) { 
    int nameDiff = e1.getName().compareTo(e2.getName()); 

    if(nameDiff != 0) { 
     return nameDiff; 
    } 

    int ageDiff = e1.getAge() - e2.getAge(); 

    if(ageDiff != 0) { 
     return ageDiff; 
    } 

    int idDiff = e1.getEmpId() - e2.getEmpId(); 

    return idDiff; 
    } 
} 
+3

A chi ha fatto l'anonimo downvote, puoi consigliare come posso migliorare la mia risposta, o almeno cosa c'è di sbagliato in essa? Grazie. – Bringer128

4

Aggiornamento

sono imbattuto in questo un momento fa: How to compare objects by multiple fields Una delle risposte legate alla ComparatorChain che richiamerà più comparatori in sequenza fino a quando un risultato diverso da zero viene ricevuto da un comparatore o tutti i comparatori vengono invocati. Questa dovrebbe probabilmente essere la tua soluzione preferita.


Forse questo (non testata) attuazione di Comparator#compare() farà il trucco.

int compare(Employee e, Employee f) 
{ 
    int val = e.name.compareTo(f.name); 

    if(val == 0) 
    { 
     val = e.age - f.age; 

     if(val == 0) 
     { 
      val = e.empId - f.empId; 
     } 
    } 

    return val; 
} 
+0

+1 per cercare vecchie domande. (E una risposta di qualità) – Bringer128

1

È possibile anche implementare l'interfaccia Comparable nella tua classe.

per esempio, qualcosa di simile:

public class Employee implements Comparable<Employee>{ 
    private int empId; 
    private String name; 
    private int age; 

    public Employee(int empId, String name, int age) { 
      // set values on attributes 

    } 
    // getters & setters 

    public int compareTo(Employee o) { 
     int ret = this.name.compareTo(o.name); 
     if(ret == 0) 
      ret = this.age - o.age; 
     if(ret == 0) 
      ret = this.empId - o.empId; 

     return ret; 
    } 
} 

quindi non c'è bisogno di implementare una classe in più per confrontare i vostri dipendenti.

1

attuarlo

public class Employee { 
    private int empId; 
    private String name; 
    private int age; 
    /** 
    * @param empId 
    * @param name 
    * @param age 
    */ 
    public Employee(int empId, String name, int age) { 
     super(); 
     this.empId = empId; 
     this.name = name; 
     this.age = age; 
    } 
    /** 
    * 
    */ 
    public Employee() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 


    public int getEmpId() { 
     return empId; 
    } 
    public void setEmpId(int empId) { 
     this.empId = empId; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public int getAge() { 
     return age; 
    } 
    public void setAge(int age) { 
     this.age = age; 
    } 

    //Compare by name, age and then id 
    public static Comparator<Employee> COMPARE_EMPLOYEE = new Comparator<Employee>() { 
     public int compare(Employee one, Employee other) { 
      //Compare Name 
      if (one.getName().compareToIgnoreCase(other.getName()) == 0) { 
       //Compare age 
       if((one.getAge() - other.getAge()) == 0) { 
        // Now check with id is useless 
        // So directly return result of compare by id 
        return one.getEmpId() - other.getEmpId(); 
       } else { //If age Not equal 
        return one.getAge() - other.getAge(); 
       } 
      } else { //If name not equal 
       return one.getName().compareToIgnoreCase(other.getName()); 
      } 
     } 
    }; 
} 

Usa:

List<Employee> contacts = new ArrayList<Employee>(); 
//Fill it. 

//Sort by address. 
Collections.sort(contacts, Employee.COMPARE_EMPLOYEE); 

Sorting an ArrayList of Contacts Leggi, questo deve aiutare voi e otterrete più idee e diversi tipi di utilizzo del comparatore.

1

guava ComparisonChain:

List<Employee> list = new ArrayList<Employee>(); 
    //... 
    Collections.sort(list, new Comparator<Employee>(){  
     @Override 
     public int compare(Employee e1, Employee e2) { 
      return ComparisonChain.start() 
       .compare(e1.empId, e2.empId) 
       .compare(e1.name, e2.name) 
       .compare(e1.age, e2.age).result(); 
    }}); 
0

Utilizzare questa:

public class Test 
{ 
    public static void main(String[] args) 
    { 
     Employee emp1 = new Employee(2, "Tom", 20); 
     Employee emp2 = new Employee(1, "Tom", 20); 
     Employee emp3 = new Employee(3, "Hank", 21); 

     List<Employee> list = new ArrayList<>(); 

     list.add(emp1); 
     list.add(emp2); 
     list.add(emp3); 

     Collections.sort(list, new Employee().new MyComparator()); 

     System.out.println(list); 
    } 
} 

class Employee 
{ 
    private int empId; 
    private String name; 
    private int age; 

    public Employee() 
    {} 

    public Employee(int empId, String name, int age) 
    { 
     this.empId = empId; 
     this.name = name; 
     this.age = age; 
    } 

    class MyComparator implements Comparator<Employee> 
    { 
     @Override 
     public int compare(Employee e1, Employee e2) 
     { 
      if(e1.name.compareTo(e2.name) == 0) 
      { 
       if(((Integer)e1.age).compareTo(e2.age) == 0) 
       { 
        return ((Integer)e1.empId).compareTo(e2.empId); 
       } 
       else 
       { 
        return ((Integer)e1.age).compareTo(e2.age); 
       } 
      } 
      return e1.name.compareTo(e2.name); 
     } 
    } 

    @Override 
    public String toString() 
    { 
     return "Employee [empId=" + empId + ", name=" + name + ", age=" + age + "]"; 
    } 
}