Comment utiliser Java comparator correctement?


Si j'ai la classe suivante:

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
}

Comment puis-je utiliser un comparateur qui compare par nom, puis par âge, puis par id?

Author: Sheehan Alam, 2011-08-19

6 answers

Vous devez l'implémenter afin qu'il commande par éléments préférés. Autrement dit, vous devez comparer par nom, alors si cette comparaison est égale, comparez par âge, etc. Un exemple est répertorié ci-dessous:

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;
  }
}
 8
Author: Bringer128, 2011-08-19 04:54:10

Mise à Jour

Est tombé sur ceci il y a un instant: Comment comparer des objets par plusieurs champsUne des réponses liées à ComparatorChain qui invoquera plusieurs comparateurs dans l'ordre jusqu'à ce qu'un résultat non nul soit reçu d'un comparateur ou que tous les comparateurs soient invoqués. Cela devrait probablement être votre solution préférée.


Peut-être que cette implémentation (non testée) de Comparator#compare() fera l'affaire.

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;
}
 4
Author: no.good.at.coding, 2017-05-23 12:00:14

Vous pouvez également implémenter l'interface Comparable dans votre classe.

Par exemple, quelque chose comme ceci:

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;
    }
}

Vous n'avez donc pas besoin d'implémenter une classe supplémentaire pour comparer vos employés.

 1
Author: Dragon8, 2011-08-19 05:08:41

L'implémenter

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());
            }
        }
    };
}

Utilisation :

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

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

Lire Trier une liste de contacts, cela doit vous aider et vous obtiendrez plus d'idées et différents types d'utilisation du Comparateur.

 1
Author: Pankaj Kumar, 2017-05-23 12:16:51

Goyave 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(); 
    }});
 1
Author: 卢声远 Shengyuan Lu, 2011-08-19 07:30:43

Utilisez ceci:

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 + "]";
    }
}
 0
Author: michal, 2015-07-27 19:02:54