Sort: how to create a custom order, then alphabetically sort in java

I have an Enum with approximately 70 fields.

I want 10 of them to be displayed in a specific order, then I want the rest to be displayed in alphabetical order using a comparator. I tried a lot of things, but I can't get it to work.

Here is an example of a listing with reduced attributes. I want to display Picard, Worf and William first, then the rest in alphabetical order

I can not use any third libraries. It must be Java. Therefore, if you want to provide answers in guava or respond with apache, please do this in addition to the explicit kernel.

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
source share
4 answers

Bad design to place additional data in your listing just for display purposes in a specific order. Instead, put all this logic in a Comparator , as shown below:

 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 (ie first) return -1; } if (ORDERED_ENTRIES.contains(o2)) { // o2 is in the ordered list, but o1 isn't. o2 is smaller (ie first) return 1; } return o1.toString().compareTo(o2.toString()); } } 

Now you can just sort:

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

which prints

 Picard Worf William Dianna Geordi Q 
+16
source

I would do it like this:

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

And in the compare method something like this:

 if (orderHint == -1) { return o1.label.compareTo(o2.label)); } return o2.orderHint-o1.orderHint; 
+2
source

List the listings you want to order for the first on your list, then use this code:

 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()); } }; 
+1
source

You can define an additional constructor in your enumeration that takes an index parameter and then provides indexes for the instances you want first (leave the ones you want in alphabetical order not indexed):

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

Then your comparator should look like this:

 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()); } }; 
0
source

All Articles