Java Sorting based on Enum constants

JavaSortingEnums

Java Problem Overview


We have an enum

enum listE {
    LE1,
    LE4,
    LE2,
    LE3
}

Furthermore, we have a list that contains the strings ["LE1","LE2","LE3","LE4"]. Is there a way to sort the list based on the enum defined order (not the natural String order).

The sorted list should be ["LE1", "LE4", "LE2", "LE3"].

Java Solutions


Solution 1 - Java

Enum<E> implements Comparable<E> via the natural order of the enum (the order in which the values are declared). If you just create a list of the enum values (instead of strings) via parsing, then sort that list using Collections.sort, it should sort the way you want. If you need a list of strings again, you can just convert back by calling name() on each element.

Solution 2 - Java

I used following to sort my List<theEnum> in an ascending order, and it worked fine for me.

Collections.sort(toSortEnumList, new Comparator<theEnum>() {
                @Override
                public int compare(theEnum o1, theEnum o2) {
                    return o1.toString().compareTo(o2.toString());
                }
            });

Solution 3 - Java

values() method returns in the order in which it is defined.

enum Test{
  A,B,X,D
}

for(Test t: Test.values()){
  System.out.println(t);
}

Output

A
B
X
D

Solution 4 - Java

Every enum constant has an ordinal value corresponding to its position in the enum declaration. You can write a comparator for your strings using the ordinal value of the corresponding enum constant.

Solution 5 - Java

Jon's answer is correct per the specification:

> Enum implements Comparable via the natural order of the enum (the order in which the values are declared).

However, I wanted to leave a Java8 example in case somebody wants to map string values to an enum and sort by the enum order. With that you can map your strings to the enum, sort using the default comparable, and then map it back using a toString. This leaves you with something like this:

enum listE {
    LE1,
    LE4,
    LE2,
    LE3
}

public static void main(String[] args) {
	List<String> originalList = Arrays.asList("LE1", "LE2", "LE3", "LE4");
	
	System.out.println("Original List: " + originalList);
	
	List<String> sortedList = originalList.stream()
			                              .map(listE::valueOf)
			                              .sorted(listE::compareTo)
			                              .map(listE::toString)
			                              .collect(Collectors.toList());
	
	System.out.println("Sorted List: " + sortedList);
}

The result would be:

  • Original List: [LE1, LE2, LE3, LE4]
  • Sorted List: [LE1, LE4, LE2, LE3]

Solution 6 - Java

If you want different sort order then provided in Enum class and you cannot modify it, just assign int to your enum fields and compare it:

public class MyComparator implements Comparator<ListE> {

    @Override
    public int compare(ListE o1, ListE o2) {
        return Integer.compare(getAssignedValue(o1), getAssignedValue(o2));
    }

    int getAssignedValue(ListE listE) {
        switch (listE) {
            case LE2:
                return 0;
            case LE1:
                return 1;
            case LE4:
                return 2;
            case LE3:
                return 3;
            default:
                return Integer.MAX_VALUE;
        }
    }

}

and then use

Collections.sort(myList, new MyComparator());

Solution 7 - Java

public class Student implements Comparable<Student>{
	
	public String studentName;
	
	public Student(String name,DayInWeek weekDay){
		this.studentName = name;
		this.studentDays = weekDay;
	}
	
	public enum DayInWeek {
		SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
	}
	public DayInWeek studentDays;
	
	@Override
	public int compareTo(Student s1) {
		if(s1.studentDays.ordinal() < this.studentDays.ordinal())
			return 1;
		else if(s1.studentDays.ordinal() > this.studentDays.ordinal())
			return -1;
		else
			return 1;
	}
}

Solution 8 - Java

you should probably look at the ordinal() method of the enum, it returns an Integer of the position the enum type appears in the enum class, so in your case LE1 = 0, LE4 = 1, etc...

Solution 9 - Java

Try to use :

add to enum field(sorted field)

like

enum MyEnum{
 private String sorted;
 MyEnum(String sorted){
  this.sorted = sorted;
 }
 String getSorted(){
  return this.sorted;
 }
}

Use TreeSet

Implement Comparator using MyEnum.sorted filed

Solution 10 - Java

If you wan to sort by ordinal you can use valueOf to convert the string and add these to an EnumSet (which is sorted by ordinal)

Otherwise you can sort the values based on an attribute of the enum. (This can be more robust and not dependent of the order the enums are declared) Use valueOf and write a custom Comparator.

Solution 11 - Java

Here is a method you can add to your enumeration to get an array of sorted enumerated constants:

  • Where Element is the name of your Enumeration

  • Where the enumerations are sorted by their toString

      public static Element[] getSortedValues(){
          return Stream.of(values()).sorted((o1,o2)->
          {
              return o1.toString().compareTo(o2.toString());
          }).
          toArray(Element[]::new);
      }
    

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSukhhhhView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaWattView Answer on Stackoverflow
Solution 3 - JavajmjView Answer on Stackoverflow
Solution 4 - JavaCyrille KaView Answer on Stackoverflow
Solution 5 - JavaAgricolaView Answer on Stackoverflow
Solution 6 - JavaAppiDevoView Answer on Stackoverflow
Solution 7 - JavaAnkush RasseView Answer on Stackoverflow
Solution 8 - Javakevin the kittenView Answer on Stackoverflow
Solution 9 - JavaSergii ZagriichukView Answer on Stackoverflow
Solution 10 - JavaPeter LawreyView Answer on Stackoverflow
Solution 11 - JavaverydulView Answer on Stackoverflow