【问题标题】:How to sort a List<Enum, Collection> by order of an enum?如何按枚举的顺序对 List<Enum, Collection> 进行排序?
【发布时间】:2012-11-19 07:26:52
【问题描述】:

枚举:

 public enum ComponentType {
    INSTRUCTION, ACTION, SERVICE, DOMAIN, INTEGRATION,  OTHER, CONTEXT;
 }

A 类:

 public class A
 {
    String name;
    ComponentType c;
    public A(String name, ComponentType c)
    {
      this.name = name;
      this.c = c;
    }

 }   

代码:

 List<A> l = new ArrayList<A>();
 l.add(new A("ZY", ACTION));  
 l.add(new A("ZY0", INSTRUCTION));  
 l.add(new A("ZY1", DOMAIN));  
 l.add(new A("ZY2", SERVICE));  
 l.add(new A("ZY3", INSTRUCTION));  
 l.add(new A("ZY4", ACTION));  

如何根据枚举顺序对列表进行排序?

【问题讨论】:

  • 我不明白您想要什么...您的示例无法编译,因为 java.util.List.add 不采用两个对象参数。
  • 对不起...我错过了类定义...刚刚编辑。现在,问题完成了
  • 您希望它按“ZY”、“ZY0” ... 还是按 ACTION、INSTRUCTION ... 排序?
  • 按 ACTION、INSTRUCTION 排序。如 ComponentType 中定义的顺序,例如指令、行动、服务、领域
  • @SubinS: Collections.sort(list) 仅在列表中的元素为 Comparable 时才有效。否则,您需要自己提供Comparator

标签: java collections enums


【解决方案1】:

您应该简单地委托给已经提供并反映声明顺序的枚举compareTo 方法(基于ordinal 值):

Collections.sort(list, (a1, a2) -> a1.getType().compareTo(a2.getType()));        

或者,如果您认为组件类型为您的元素提供了“自然顺序”,您可以让 A 类本身实现 Comparable 并将 compareTo 方法委托给 ComponentType 之一。

【讨论】:

  • 他要按Enum顺序来做,不需要对枚举名称进行字母顺序排序,只需要枚举顺序。所以不会 Collections.sort(list) 应该工作。
  • 你为什么提出“枚举名称的字母顺序”?您是否有可能评论了错误的答案(我看到有另一个答案确实涉及您提到的顺序)? :)
  • 是的,我认为这是一个错误,我的意思是可能有其他评论。但是 Collections.sort() 不会工作吗?
  • 您的答案有效.. 我评论 bellium 答案,因为输出与所提出的问题不同.... 如果排序顺序是 alpahabetally 中定义的序数顺序,则将使用 bellium 答案枚举
【解决方案2】:

使一个工具具有可比性。如果要按枚举名称排序,请使用以下 compareTo 方法:

public int compareTo(A a) {
    return a.c.getName().compareTo(c.getName());
}

如果您想按您输入枚举的顺序进行排序,请比较序数值:

public int compareTo(A a) {
    return a.c.ordinal().compareTo(c.ordinal());
}

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,但我无法修改我的 Enum 课程并且顺序错误。这就是为什么我不能在枚举对象上使用简单的compareTo。解决方法很简单,给每个 Enum 字段赋值 int 值,然后比较:

    public class MyComparator implements Comparator<A> {
    
        @Override
        public int compare(A o1, A o2) {
            return Integer.compare(getAssignedValue(o1.getComponentType()), getAssignedValue(o2.getComponentType()));
        }
    
        int getAssignedValue(ComponentType componentType) {
            switch (componentType) {
                case OTHER:
                    return 0;
                case CONTEXT:
                    return 1;
                case SERVICE:
                    return 2;
                case DOMAIN:
                    return 3;
                case INTEGRATION:
                    return 4;
                case ACTION:
                    return 5;
                case INSTRUCTION:
                    return 6;
                default:
                    return Integer.MAX_VALUE;
    
            }
        }
    
    }
    

    然后:

    Collections.sort(list, new MyComparator);
    

    【讨论】:

      【解决方案4】:

      根据java.util.Collections.sort,一种方法是:

      1. 使class A实现Comparable接口,这包括编写int compare(A other)方法。
      2. 致电Collections.sort(l);

      【讨论】:

        【解决方案5】:

        如果需要根据 ENUM 对类进行排序,为了保持一致性,我们必须使用 ENUM 的 compareTo(which if final) 方法。

        将此方法添加到 A 类将有助于并保持一致的行为。

        @Override
        public int compareTo(A o) {
            return this.c.compareTo(o.c);
        }
        

        【讨论】:

          【解决方案6】:

          看来您应该使用 EnumMap,因为它们是按键自然排序的。

          public static void add(Map<ComponentType, List<A>> map, A a) {
              List<A> as = map.get(a.c);
              if(as == null) map.put(a.c, as = new ArrayList<A>());
              as.add(a);
          }
          
          Map<ComponentType, List<A>> map = new EnumMap<ComponentType, List<A>>(ComponentType.class);
          add(map, new A("ZY", ComponentType.ACTION));
          add(map, new A("ZY0", ComponentType.INSTRUCTION));
          add(map, new A("ZY1", ComponentType.DOMAIN));
          add(map, new A("ZY2", ComponentType.SERVICE));
          add(map, new A("ZY3", ComponentType.INSTRUCTION));
          add(map, new A("ZY4", ComponentType.ACTION));
          

          【讨论】:

          • 这种方法的唯一问题是“ZY”和“ZY0”会丢失,因为此代码部分添加了具有相同类型的其他实例。
          • 是的,EnumMap 不允许重复。修正了答案。
          • 但是,鉴于问题标题中提到的怪异类型,您可能最接近答案;如果他的意思是Map&lt;Enum, Collection&gt;,那么您需要做的就是将您的EnumMap 更改为EnumMap&lt;ComponentType, Collection&lt;A&gt;&gt;
          【解决方案7】:

          枚举 compareTo 似乎是最终的,不能被覆盖 Why is compareTo on an Enum final in Java?

          只需执行 Collections.sort() 即可根据需要按枚举顺序对列表进行排序

          【讨论】:

            【解决方案8】:

            这是你必须做的:

                List<A> l = new ArrayList<A>();
                l.add(new A("ZY", ComponentType.ACTION));  
                l.add(new A("ZY0", ComponentType.INSTRUCTION));  
                l.add(new A("ZY1", ComponentType.DOMAIN));  
                l.add(new A("ZY2", ComponentType.SERVICE));  
                l.add(new A("ZY3", ComponentType.INSTRUCTION));  
                l.add(new A("ZY4", ComponentType.ACTION));
            
                Collections.sort(l, new Comparator<A>()
                {
                    @Override
                    public int compare(A o1, A o2)
                    {
                        return o1.c.toString().compareTo(o2.c.toString());
                    }
                });
            

            【讨论】:

              【解决方案9】:

              首先,你没有List&lt;Enum, Collection&gt;,因为这是不可能的,你有一个List&lt;A&gt;,并且应该如下声明:

              List&lt;A&gt; list = new LinkedList&lt;&gt;();

              您正在尝试在接口中实例化,这是不可能的,并且是编译时错误。

              如果您想对A 的列表进行排序,您应该进行比较:

              public class A implements Comparable&lt;A&gt;

              并重写compareTo()方法如下:

              @Override
              public int compareTo(A other) {
                  return c.ordinal() - other.c.ordinal();
              }
              

              要对您的列表进行排序,您可以调用:

              Collections.sort(list);

              【讨论】:

                【解决方案10】:

                首先 - 开始使用Generics。所以你的代码会是

                List&lt;A&gt; l = new ArrayList&lt;A&gt;();

                对于您的问题,让您的 A 类实现 Comparable 并覆盖方法 compareTo ,您可以在其中放置表达式进行排序。 Example here

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-01-09
                  • 1970-01-01
                  • 2021-06-07
                  • 2010-12-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多