如何正确使用Java比较器?

时间:2011-08-19 04:44:54

标签: java oop sorting comparator

如果我有以下课程:

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
}

如何使用按名称比较的比较器,然后是年龄,然后是id?

6 个答案:

答案 0 :(得分:8)

您需要实现它,以便按首选元素进行排序。也就是说,您需要按名称进行比较,如果该比较相等,则按年龄等进行比较。下面列出了一个示例:

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

答案 1 :(得分:4)

<强>更新

刚才看到:How to compare objects by multiple fieldsComparatorChain相关联的答案之一,它将按顺序调用多个比较器,直到从比较器接收到非零结果或调用所有比较器。这应该是您首选的解决方案。


也许Comparator#compare()的这种(未经测试的)实现可以解决问题。

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

答案 2 :(得分:1)

您还可以在班级中实现Comparable Interface。

例如,像这样:

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

因此您无需实施额外的课程来比较您的员工。

答案 3 :(得分: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(); 
    }});

答案 4 :(得分:0)

使用此:

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 + "]";
    }
}

答案 5 :(得分:0)

比较器接口定义了两种方法:compare()equals()

compare()方法比较两个元素的顺序: int compare(Object obj1, Object obj2)

obj1obj2是要比较的对象。如果对象相等,则此方法返回零。如果obj1大于obj2,则返回正值。否则,将返回负值。

通过覆盖compare(),您可以更改对象的排序方式。例如,要以相反的顺序排序,您可以创建一个比较器,以将比较的结果反转。

equals()方法测试对象是否等于调用比较器:boolean equals(Object obj)

obj是要测试是否相等的对象。如果obj和调用对象都是Comparator对象,并且使用相同的顺序,则该方法返回true。否则,它返回false。

示例:

import java.util.*;

class Dog implements Comparator<Dog>, Comparable<Dog> {
   private String name;
   private int age;
   Dog() {
   }

   Dog(String n, int a) {
      name = n;
      age = a;
   }

   public String getDogName() {
      return name;
   }

   public int getDogAge() {
      return age;
   }

   // Overriding the compareTo method
   public int compareTo(Dog d) {
      return (this.name).compareTo(d.name);
   }

   // Overriding the compare method to sort the age 
   public int compare(Dog d, Dog d1) {
      return d.age - d1.age;
   }
}

public class Example {

   public static void main(String args[]) {
      // Takes a list o Dog objects
      List<Dog> list = new ArrayList<Dog>();

      list.add(new Dog("Shaggy", 3));
      list.add(new Dog("Lacy", 2));
      list.add(new Dog("Roger", 10));
      list.add(new Dog("Tommy", 4));
      list.add(new Dog("Tammy", 1));
      Collections.sort(list);   // Sorts the array list

      for(Dog a: list)   // printing the sorted list of names
         System.out.print(a.getDogName() + ", ");

      // Sorts the array list using comparator
      Collections.sort(list, new Dog());
      System.out.println(" ");

      for(Dog a: list)   // printing the sorted list of ages
         System.out.print(a.getDogName() +"  : "+ a.getDogAge() + ", ");
   }
}

查看更多Java Comparator示例。