假设你有一些对象,它们有几个字段可以比较:

public class Person {

    private String firstName;
    private String lastName;
    private String age;

    /* Constructors */

    /* Methods */

}

所以在这个例子中,当你问if:

a.compareTo(b) > 0

你可能会问a的姓是不是在b的姓之前,或者a的年龄是不是比b大,等等……

在不增加不必要的混乱或开销的情况下,在这些类型的对象之间进行多重比较的最干净的方法是什么?

comparable接口只允许通过一个字段进行比较 在我看来,添加大量的比较方法(如compareByFirstName(), compareByAge()等)是混乱的。

那么最好的解决办法是什么呢?


当前回答

它很容易做到使用谷歌的番石榴库。

例如对象。equals (name, name2) &&对象。Equal (age, age2) &&…

更多的例子:

https://stackoverflow.com/a/5039178/1180621

其他回答

您应该实现Comparable <Person>。假设所有字段都不为空(为了简单起见),年龄是int型,比较排名是第一,最后,年龄,compareTo方法非常简单:

public int compareTo(Person other) {
    int i = firstName.compareTo(other.firstName);
    if (i != 0) return i;

    i = lastName.compareTo(other.lastName);
    if (i != 0) return i;

    return Integer.compare(age, other.age);
}

要连续排序多个字段,请尝试ComparatorChain

A ComparatorChain is a Comparator that wraps one or more Comparators in sequence. The ComparatorChain calls each Comparator in sequence until either 1) any single Comparator returns a non-zero result (and that result is then returned), or 2) the ComparatorChain is exhausted (and zero is returned). This type of sorting is very similar to multi-column sorting in SQL, and this class allows Java classes to emulate that kind of behaviour when sorting a List. To further facilitate SQL-like sorting, the order of any single Comparator in the list can >be reversed. Calling a method that adds new Comparators or changes the ascend/descend sort after compare(Object, Object) has been called will result in an UnsupportedOperationException. However, take care to not alter the underlying List of Comparators or the BitSet that defines the sort order. Instances of ComparatorChain are not synchronized. The class is not thread-safe at construction time, but it is thread-safe to perform multiple comparisons after all the setup operations are complete.

import com.google.common.collect.ComparisonChain;

/**
 * @author radler
 * Class Description ...
 */
public class Attribute implements Comparable<Attribute> {

    private String type;
    private String value;

    public String getType() { return type; }
    public void setType(String type) { this.type = type; }

    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }

    @Override
    public String toString() {
        return "Attribute [type=" + type + ", value=" + value + "]";
    }

    @Override
    public int compareTo(Attribute that) {
        return ComparisonChain.start()
            .compare(this.type, that.type)
            .compare(this.value, that.value)
            .result();
    }

}

我认为如果你的比较算法是“聪明的”,那就更令人困惑了。我会选择你建议的众多比较方法。

对我来说唯一的例外就是平等。对于单元测试,重写. equals(在.net中)对我来说很有用,以便确定两个对象之间的几个字段是否相等(而不是引用是否相等)。

Java 8通过lambda方式我们可以通过方法引用进行比较。 学生POJO

public class Student {
int id;
String firstName;
String lastName;
String subject;

public Student(int id, String firstName, String lastName, String subject) {
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.subject = subject;
}
enter code here

现在我们可以根据

1. id - > FirstName - > LastName - > 2。主题- > id - > FirstName - > LastName

我们将在数组Stream中使用Comparator

public class TestComprator {
public static void main(String[] args) {
    Student s1= new Student(108, "James", "Testo", "Physics");
    Student s2= new Student(101, "Fundu", "Barito", "Chem");
    Student s3= new Student(105, "Sindhu", "Sharan", "Math");
    Student s4= new Student(98, "Rechel", "Stephen", "Physics");
    System.out.printf("----------id->FirstName->LastName->Subject-------------");
    Arrays.asList(s1,s2,s3,s4).stream()
            .sorted(Comparator.comparing(Student::getId)
                    .thenComparing(Student::getFirstName)
                .thenComparing(Student::getLastName)
                .thenComparing(Student::getSubject))
            .forEach(System.out::println);

    System.out.printf("----Subject->id->FirstName->LastName ------\n");
    Arrays.asList(s1,s2,s3,s4).stream()
            .sorted(Comparator. comparing(Student::getSubject)
                    .thenComparing(Student::getId)
                    .thenComparing(Student::getFirstName)
                    .thenComparing(Student::getLastName)
                   )
            .forEach(System.out::println);
}

}

输出:

`----------id->FirstName->LastName->Subject-------------
Student{id=98, firstName='Rechel', lastName='Stephen', subject='Physics'}
Student{id=101, firstName='Fundu', lastName='Barito', subject='Chem'}
Student{id=105, firstName='Sindhu', lastName='Sharan', subject='Math'}
Student{id=108, firstName='James', lastName='Testo', subject='Physics'}
 ----Subject->id->FirstName->LastName ------
Student{id=101, firstName='Fundu', lastName='Barito', subject='Chem'}
Student{id=105, firstName='Sindhu', lastName='Sharan', subject='Math'}
Student{id=98, firstName='Rechel', lastName='Stephen', subject='Physics'}
Student{id=108, firstName='James', lastName='Testo', subject='Physics'}