簡體   English   中英

排序:如何創建特定的自定義順序,然后在java中進行字母排序

[英]Sorting: How to create a particular custom order, then alphabetic sort in java

我有一個大約70個領域的Enum。

我希望其中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);

為了按特定順序顯示,在枚舉中放置其他數據是不好的設計。 相反,將所有邏輯放在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

我會這樣做:

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;

在列表中首先列出您想要特殊訂購的枚舉,然后使用以下代碼:

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());
    }
};

您可以在枚舉中定義一個額外的構造函數,它接受一個索引參數,然后為您想要的實例提供索引(保留您想要按字母順序排列的索引):

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());
                }
        };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM