10

我有一个包含大约 70 个字段的枚举。

我希望其中 10 个按特定顺序显示,然后我希望其余的使用比较器按字母顺序显示。我已经尝试了很多东西,但我无法让它发挥作用。

这是一个带有减少属性的示例枚举, 我希望 Picard、Worf 和 William 先显示,然后按字母顺序显示其余的

我不能使用任何第三个库。它必须是java核心。因此,如果您想提供 guava 答案或 apache commons 答案,请在 java core 之外提供。

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);
4

4 回答 4

27

仅出于按特定顺序显示的目的而在枚举中放置其他数据是不好的设计。相反,将所有这些逻辑放在你的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
于 2013-02-26T14:54:40.680 回答
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;
于 2013-02-26T14:42:03.773 回答
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());
    }
};
于 2013-02-26T14:48:55.993 回答
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());
                }
        };
于 2013-02-26T14:48:36.730 回答