How to sort the list <Enum, Collection> by order of listing?
Enum:
public enum ComponentType { INSTRUCTION, ACTION, SERVICE, DOMAIN, INTEGRATION, OTHER, CONTEXT; } Grade 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 the list according to the order of listing?
You should simply delegate the enum compareTo method, which is already provided and reflects the declaration order (based on ordinal value):
Collections.sort(list, (a1, a2) -> a1.getType().compareTo(a2.getType())); Or, if you think the component type provides a “natural order” for your elements, you can force class A to implement Comparable , and delegate the compareTo method to the ComponentType method.
Create a Comparable Tool. If you want to sort by enumeration names, use this compareTo method:
public int compareTo(A a) { return acgetName().compareTo(c.getName()); } If you want to sort by the order that you typed your enums, compare the ordinal values:
public int compareTo(A a) { return acordinal().compareTo(c.ordinal()); } According to java.util.Collections.sort , one way to do this is:
- Create a
class AComparableinterface, including anint compare(A other)method entry. - Call
Collections.sort(l);
It seems you should use EnumMap, as they are naturally sorted by key.
public static void add(Map<ComponentType, List<A>> map, A a) { List<A> as = map.get(ac); if(as == null) map.put(ac, 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)); First of all, start using Generics . So your code will be
List<A> l = new ArrayList<A>();
And for your question, let your class class implement Comparable and override the compareTo method, where you can put an expression to sort. Example here
Enum compareTo seems final and cannot be reevaluated Why compareTo on the Enum finale in Java?
Just make Collections.sort (), which will order the list in order of listing as needed.
Here is what you need 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()); } }); First of all, you do not have List<Enum, Collection> , since this is not possible, you have List<A> and shoud declare it as follows:
List<A> list = new LinkedList<>();
You are trying to create an instance in the interface, which is impossible and is a compile-time error.
If you want to sort list A , you must do 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 the list, you can call:
Collections.sort(list);
I had the same problem, but I could not change my Enum class, and the order was wrong. This is why I could not use a simple compareTo for an enum object. The solution is very simple, just assign an int value to each 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);