使用2个条件在Java中对列表进行排序
我有一个对象列表。 每个对象都包含一个String
和一个Date
(以及其他对象)。
我想首先按String
排序,然后按Date
排序。
怎么可能以最干净的方式完成?
谢谢!
Krt_Malta
给定一个如下所示的对象类:
public class MyObject { public String getString() { ... } public Date getDate() { ... } ... }
编写自定义比较器类,如下所示:
public class ObjectComparator implements Comparator{ public int compare(Object obj1, Object obj2) { MyObject myObj1 = (MyObject)obj1; MyObject myObj2 = (MyObject)obj2; stringResult = myObj1.getString().compareTo(myObj2.getString()); if (stringResult == 0) { // Strings are equal, sort by date return myObj1.getDate().compareTo(myObj2.getDate()); } else { return stringResult; } } }
然后排序如下:
Collections.sort(objectList, new ObjectComparator());
使用Java 8,这非常简单。 特定
class MyClass { String getString() { ... } Date getDate() { ... } }
您可以按如下方式轻松对列表进行排序:
List list = ... list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
使用compare(a,b)
方法实现自定义Comparator
,如下所示:
普通Java:
public int compare(YourObject o1, YourObject o2) { int result = o1.getProperty1().compareTo(o2.getProperty1())); if(result==0) result = o1.getProperty2().compareTo(o2.getProperty2()); return result; }
使用Guava (使用ComparisonChain
):
public int compare(YourObject o1, YourObject o2) { return ComparisonChain.start() .compare(o1.getProperty1(), o2.getProperty1()) .compare(o1.getProperty2(), o2.getProperty2()) .result(); }
使用Commons / Lang (使用CompareToBuilder
):
public int compare(YourObject o1, YourObject o2) { return new CompareToBuilder() .append(o1.getProperty1(), o2.getProperty1()) .append(o1.getProperty2(), o2.getProperty2()) .toComparison(); }
(所有三个版本都是等价的,但普通的Java版本是最冗长的,因此最容易出错。所有三个解决方案都假设o1.getProperty1()
和o1.getProperty2()
实现了Comparable
)。
(取自我此前的答案 )
现在做Collections.sort(yourList, yourComparator)
比较器的答案是正确但不完整的。
StringAndDateComparator implements Comparator { public int compare(MyObject first, MyObject second) { int result = first.getString().compareTo(second.getString()); if (result != 0) { return result; } else { return first.getDate().compareTo(second.getDate()); } }
GlazedLists有一个很好的实用方法可以将不同的比较器链接在一起,以免您编写此样板文件。 有关更多信息,请参阅chainComparators方法。
试试这个方法:
Collections.sort(list, comparator)
您当然应该为您的对象提供自定义Comparator实现,如Manoj所述。
使用java 8和并行排序技术,我们也可以实现如下:
List empss = getEmployees(); Comparator combinedComparator = Comparator.comparing(Employee::getFName) .thenComparing(Employee::getLName); Employee[] emppArr = employees.toArray(new Employee[empss.size()]); //Parallel sorting Arrays.parallelSort(emppArr, combinedComparator);