[英]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)
obj1
和obj2
是要比較的對象。 如果對象相等,則此方法返回零。 如果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.