我有一個對象列表。每個對象包含String
和Date
(等等)。使用2個標準對Java進行列表排序
我想先按String
排序,然後按Date
排序。
這怎麼可能以最乾淨的方式完成?
謝謝!
Krt_Malta
我有一個對象列表。每個對象包含String
和Date
(等等)。使用2個標準對Java進行列表排序
我想先按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());
比較器的答案是正確的,但不完整。
StringAndDateComparator implements Comparator<MyObject> {
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方法。
實現自定義Comparator
,使用compare(a,b)
方法如下所示:
普通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
)。
(來自this previous answer of mine兩者)
使用Java 8,這是很容易的。鑑於
class MyClass {
String getString() { ... }
Date getDate() { ... }
}
您可以按如下容易列表排序:
List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
這個答案應該更高一些 – Joshua 2017-03-24 12:03:41
這是最優雅和正確的答案。 – ManoDestra 2017-05-01 17:52:02
用java 8和並行排序技術,我們也可以做到這一點,如下所示:
List<Employee> empss = getEmployees();
Comparator<Employee> combinedComparator = Comparator.comparing(Employee::getFName)
.thenComparing(Employee::getLName);
Employee[] emppArr = employees.toArray(new Employee[empss.size()]);
//Parallel sorting
Arrays.parallelSort(emppArr, combinedComparator);
@Krt_Malta最清除一個?我不這麼認爲。首先,它使用1.5以前的非通用版本的比較器,這是比較冗長和容易出錯的。例如,I82Much的答案要好得多。 – 2011-04-08 14:03:30
我實際上會同意我自己,我應該完成比較器的通用版本,並且如果您很樂意將該依賴項引入您的項目,Guava比較鏈聽起來像是值得研究的東西。 (推測它也有很多其他的好東西。) – unnamedwill 2011-04-13 10:41:50
@unnamed出於好奇,如果你同意最好用比較器,爲什麼不編輯你的答案?在這個時候,I82Much的回答是第三票,所以一些非常倉促的人可能不會閱讀它或這些評論,只是在沒有泛型的情況下實現你的答案。 –
Blueriver
2016-10-14 14:51:15