2011-04-08 83 views

回答

16

給定一個對象類,看起來像這樣:

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()); 
+2

@Krt_Malta最清除一個?我不這麼認爲。首先,它使用1.5以前的非通用版本的比較器,這是比較冗長和容易出錯的。例如,I82Much的答案要好得多。 – 2011-04-08 14:03:30

+0

我實際上會同意我自己,我應該完成比較器的通用版本,並且如果您很樂意將該依賴項引入您的項目,Guava比較鏈聽起來像是值得研究的東西。 (推測它也有很多其他的好東西。) – unnamedwill 2011-04-13 10:41:50

+0

@unnamed出於好奇,如果你同意最好用比較器,爲什麼不編輯你的答案?在這個時候,I82Much的回答是第三票,所以一些非常倉促的人可能不會閱讀它或這些評論,只是在沒有泛型的情況下實現你的答案。 – Blueriver 2016-10-14 14:51:15

6

比較器的答案是正確的,但不完整。

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方法。

6

實現自定義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兩者)​​


現在要做Collections.sort(yourList, yourComparator)

12

使用Java 8,這是很容易的。鑑於

class MyClass { 
    String getString() { ... } 
    Date getDate() { ... } 
} 

您可以按如下容易列表排序:

List<MyClass> list = ... 
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate)); 
+2

這個答案應該更高一些 – Joshua 2017-03-24 12:03:41

+0

這是最優雅和正確的答案。 – ManoDestra 2017-05-01 17:52:02

1

用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); 
相關問題