2013-02-26 44 views
4

我有一個約70個字段的Enum。排序:如何創建特定的自定義訂單,然後按字母順序排序java

我希望其中的10個以特定順序顯示,然後我希望其餘的按字母順序使用比較器顯示。我嘗試過很多東西,但是我無法完成它的工作。

下面是一個示例枚舉與降低屬性 我想要的Picard,的Worf和William首先顯示,然後,其餘按字母順序

我不能使用任何第三庫。它必須是Java核心。所以如果你想提供番石榴的答案,或者apache commons的答案,除了java核心之外,請這樣做。

public enum StarTrek { 

    JeanLucPicard("Picard"), 
    GeordiLaForge("Geordi"), 
    DiannaTroi("Dianna"), 
    Worf("Worf"), 
    WilliamRiker("William"), 
    Q("Q"); 

    private String label; 

    StarTrek(String label) { this.label = label; } 

    @Override public String toString() { return label; } 
} 

    List<StarTrek> specificOrder = Arrays.asList(StarTrek.JeanLucPicard, StarTrek.Worf, StarTrek.WilliamRiker); 

    Comparator<StarTrek> comp = new Comparator<StarTrek>() { 
      @Override 
      public int compare(StarTrek o1, StarTrek o2) { 
       //TODO: loop through the specific order, and display those first, then for the rest, go alphabetic 
       return 0; 
      } 
    }; 

    List<StarTrek> all = Arrays.asList(StarTrek.values()); 
    Collections.sort(all, comp); 
+1

爲什麼不這樣做的兩個步驟? – 2013-02-26 14:36:47

+0

我已經通過不使用排序來解決它,只是刪除和添加集合,但我想用排序來解決它。它更好。我也只想打電話給排序 – 2013-02-26 14:40:54

+0

我不太確定它更好。兩個步驟對我來說會更具可讀性,並阻止您使用僅用於顯示的元數據污染您的枚舉類。 – 2013-02-26 14:44:09

回答

16

它是壞的設計將額外的數據放在您的枚舉中,僅用於以特定順序顯示的目的。取而代之的是,將所有的邏輯在你的Comparator,如下圖所示:

public class StarTrekSorter implements Comparator<StarTrek> { 

    private static final List<StarTrek> ORDERED_ENTRIES = Arrays.asList(
     StarTrek.JeanLucPicard, StarTrek.Worf, StarTrek.WilliamRiker); 

    @Override 
    public int compare(StarTrek o1, StarTrek o2) { 
    if (ORDERED_ENTRIES.contains(o1) && ORDERED_ENTRIES.contains(o2)) { 
     // Both objects are in our ordered list. Compare them by 
     // their position in the list 
     return ORDERED_ENTRIES.indexOf(o1) - ORDERED_ENTRIES.indexOf(o2); 
    } 

    if (ORDERED_ENTRIES.contains(o1)) { 
     // o1 is in the ordered list, but o2 isn't. o1 is smaller (i.e. first) 
     return -1; 
    } 

    if (ORDERED_ENTRIES.contains(o2)) { 
     // o2 is in the ordered list, but o1 isn't. o2 is smaller (i.e. first) 
     return 1; 
    } 

    return o1.toString().compareTo(o2.toString()); 
    } 
} 

現在,你可以排序:

public static void main(String[] args) { 

    List<StarTrek> cast = Arrays.asList(StarTrek.values()); 

    Collections.sort(cast, new StarTrekSorter()); 

    for (StarTrek trek : cast) { 
    System.out.println(trek); 
    } 
} 

它打印

Picard 
Worf 
William 
Dianna 
Geordi 
Q 
+4

+1我喜歡這個回答。你對設計問題是正確的。 – Kai 2013-02-26 15:02:59

+0

請你一步一步解釋發生了什麼事?它很難理解這個比較器 – 2013-02-26 15:16:40

+0

@Shervin我已經添加了一些評論來嘗試和幫助。 「比較」方法總是很難把你的頭圍繞。 – 2013-02-26 20:24:41

2

我會做這樣的:

JeanLucPicard("Picard", 0), 
GeordiLaForge("Geordi"), 
DiannaTroi("Dianna"), 
Worf("Worf", 1), 
WilliamRiker("William", 2), 
Q("Q"); 

StarTrek(String label) { this(label, -1); } 
StarTrek(String label, int orderHint) { this.label=label; this.orderHint=orderHint; } 

而在compare方法是這樣的:

if (orderHint == -1) { 
    return o1.label.compareTo(o2.label)); 
} 
return o2.orderHint-o1.orderHint; 
+0

除了更改枚舉實現之外,沒有其他方法嗎? – 2013-02-26 14:51:05

+0

@Shervin,是的,檢查[我的答案](http://stackoverflow.com/a/15092169/474189)。 – 2013-02-26 14:55:22

0

你可以定義你的枚舉額外的構造函數,它接受一個索引參數,然後爲您想要首先執行的實例提供索引(將未按索引順序排列的字母順序排列):

enum StarTrek { 

    JeanLucPicard("Picard"), 
    GeordiLaForge("Geordi"), 
    DiannaTroi("Dianna"), 
    Worf("Worf", 2), 
    WilliamRiker("William", 1), 
    Q("Q"); 

    private final String label; 
    private final Integer index; 

    StarTrek(final String label, final Integer index) { this.label = label; this.index = index; } 

    StarTrek(final String label) { this.label = label; this.index = Integer.MAX_VALUE; } 

    @Override public String toString() { return label; } 

    public Integer getIndex() { 
     return index; 
    } 
} 

那麼你的比較必須是這樣的:

final Comparator<StarTrek> comp = new Comparator<StarTrek>() { 
       @Override 
       public int compare(final StarTrek o1, final StarTrek o2) { 
        if (!o1.getIndex().equals(o2.getIndex())) { 
         return o1.getIndex().compareTo(o2.getIndex()); 
        } 
        return o1.toString().compareTo(o2.toString()); 
       } 
     }; 
1

名單要在列表中第一個特別定製的枚舉,然後使用此代碼:

Comparator<StarTrek> comp = new Comparator<StarTrek>() { 
    public int compare(StarTrek o1, StarTrek o2) { 
     if (o1.ordinal() < 3) 
      return o2.ordinal() < 3 ? o1.ordinal() - o2.ordinal() : 1; 
     return o2.ordinal() < 3 ? -1 : o1.name().compareTo(o2.name()); 
    } 
}; 
相關問題