簡體   English   中英

如何正確使用Java比較器?

[英]How to use Java comparator properly?

如果我有以下課程:

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進行比較的比較器?

您需要實現它,以便它按首選元素排序。 也就是說,您需要按名稱進行比較,如果該比較相等,則按年齡進行比較,等等。下面列出了一個示例:

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

更新資料

剛才提到了這一點: 如何通過多個字段比較對象鏈接到ComparatorChain的答案之一將依次調用多個比較器,直到從比較器收到非零結果或調用所有比較器為止。 這可能是您的首選解決方案。


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

您也可以在您的類中實現可比較接口。

例如,如下所示:

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

因此您不必實施額外的課程來比較您的員工。

實施它

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

使用 :

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

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

閱讀對聯系人的ArrayList進行排序 ,這必須對您有所幫助,您將獲得更多的想法以及使用Comparator的不同類型。

番石榴比較鏈:

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

用這個:

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

Comparator接口定義了兩個方法: 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比較器示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM