8

Enum:

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

Class A :

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

 }   

Code:

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

How to sort list according to enum order?

Shashi
  • 12,487
  • 17
  • 65
  • 111

10 Answers10

7

You should simply delegate to the enum compareTo method which is already provided and reflects the declaration order (based on the ordinal value):

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

Or, if you think that the component type provides the "natural order" for your elements, you can make the A class itself implement Comparable and also delegate the compareTo method to the ComponentType one.

Lii
  • 11,553
  • 8
  • 64
  • 88
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
  • 1
    he wants to do it in Enum order, no need to do the alphabetic order sorting of enum names, just enum order. So wont Collections.sort(list) should work. – Subin Sebastian Nov 19 '12 at 07:38
  • Why did you bring up the "alphabetic order of enum names" ? Is it possible that you commented on the wrong answer (I see there's an other answer that does involve the order you mentioned) ? :) – Costi Ciudatu Nov 19 '12 at 07:42
  • Ya I think that was a mistake , i meant some other comment may be. But wont Collections.sort() work? – Subin Sebastian Nov 19 '12 at 07:54
  • Your answer works.. I comment on bellium answer because the output is differed with the question asked.... The bellium answer will be used if the order of sorting is alpahabetically order of ordinal defined in an Enum – Shashi Nov 19 '12 at 08:08
3

Make A implement Comparable. If you want to sort by the names of the enums, use this compareTo method:

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

If you want to sort by the order you have typed your enums, compare the ordinal values:

public int compareTo(A a) {
    return a.c.ordinal().compareTo(c.ordinal());
}
Aleksander Blomskøld
  • 18,374
  • 9
  • 76
  • 82
3

I had the same problem but I couldn't modified my Enum class and the order was wrong. That's why I couldn't use simple compareTo on enum object. The solution is very simple, just assign the int value for every Enum field and then compare it:

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;

        }
    }

}

And then:

Collections.sort(list, new MyComparator);
AppiDevo
  • 3,195
  • 3
  • 33
  • 51
1

According to java.util.Collections.sort, one way to do this is:

  1. Make class A implement the Comparable interface, this includes writing a int compare(A other) method.
  2. Call Collections.sort(l);
xiaofeng.li
  • 8,237
  • 2
  • 23
  • 30
1

It appears you should be using an EnumMap as they are naturally sorted by the key.

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));
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • The only problem with this approach is that "ZY" and "ZY0" will get lost as there are other instances with the same type added by this code section. – Costi Ciudatu Nov 19 '12 at 10:17
  • True, EnumMap doesn't allow duplicates. Fixed the answer. – Peter Lawrey Nov 19 '12 at 10:20
  • 2
    However, given the weird type mentioned in the question title, you may be the closest to the answer; if he actually meant `Map`, then all you need to do is change your `EnumMap` to an `EnumMap>` – Costi Ciudatu Nov 19 '12 at 10:24
1

If it is required to sort the class based on ENUM, for consistency purpose we must use the ENUM's compareTo(which if final) method.

Adding this method to A class will help and keep the consistent behaviour.

@Override
public int compareTo(A o) {
    return this.c.compareTo(o.c);
}
Vishal
  • 3,189
  • 1
  • 15
  • 18
0

First of all - start using Generics. So your code woudl be

List<A> l = new ArrayList<A>();

And for your question, let your A class implement Comparable and override the method compareTo where you can put the expression for sorting. Example here

Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
0

Enum compareTo seems to be final and cant be overriden Why is compareTo on an Enum final in Java?

Just do Collections.sort() which will order the list in enum order as you need

Community
  • 1
  • 1
Subin Sebastian
  • 10,870
  • 3
  • 37
  • 42
0

Here is what you have to do:

    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());
        }
    });
bellum
  • 3,642
  • 1
  • 17
  • 22
0

First of all, you don't have a List<Enum, Collection> as this is impossibile, you have a List<A> and shoud declare it as follows:

List<A> list = new LinkedList<>();

You are trying to instantiate in interface, which is not possible and is a compile time error.

If you want to sort a List of A's you should make a comparable:

public class A implements Comparable<A>

and override the compareTo() method as follows:

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

To sort your List you can call:

Collections.sort(list);

jlordo
  • 37,490
  • 6
  • 58
  • 83