Reputation: 15274
I have an unsorted list but I want to sort in a custom way i.e.
item_one_primary.pls
item_one_secondary.pls
item_one_last.pls
item_two_last.pls
item_two_primary.pls
item_two_secondary.pls
item_three_secondary.pls
item_three_last.pls
item_three_primary.pls
Here is my predefined order : primary, secondary, last
Above unordered list once the ordering is applied should look like this :
item_one_primary.pls
item_one_secondary.pls
item_one_last.pls
item_two_primary.pls
item_two_secondary.pls
item_two_last.pls
item_three_primary.pls
item_three_secondary.pls
item_three_last.pls
I tried something with comparator but I end up something like this :
item_one_primary.pls
item_two_primary.pls
item_three_primary.pls
...
Does anyone have an idea how to get this sorted?
Here is some code I've used :
List<String> predefinedOrder;
public MyComparator(String[] predefinedOrder) {
this.predefinedOrder = Arrays.asList(predefinedOrder);
}
@Override
public int compare(String item1, String item2) {
return predefinedOrder.indexOf(item1) - predefinedOrder.indexOf(item2);
}
I didn't include the splits(first split by dot(.) second split by underscore(_) to get the item in pre-ordered list).
Upvotes: 5
Views: 3381
Reputation: 8214
A solution using the Google Guava API yields a simple and readable result:
// some values
List<String> list = Lists.newArrayList("item_one_primary", "item_one_secondary", "item_one_last");
// define an explicit ordering that uses the result of a function over the supplied list
Ordering o = Ordering.explicit("primary", "secondary", "last").onResultOf(new Function<String, String>() {
// the function splits a values by '_' and uses the last element (primary, secondary etc.)
public String apply(String input) {
return Lists.newLinkedList(Splitter.on("_").split(input)).getLast();
}
});
// the ordered result
System.out.println("o.sortedCopy(list); = " + o.sortedCopy(list));
Upvotes: 2
Reputation: 5641
You have to use a Comparator
that checks first the item number and only if they are equal, check your predefined order.
Try something like this:
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
String[] a1 = s1.split("_");
String[] a2 = s2.split("_");
/* If the primary elements of order are equal the result is
the order of the second elements of order */
if (a1[1].compareTo(a2[1]) == 0) {
return a1[2].compareTo(a2[2]);
/* If they are not equal, we just order by the primary elements */
} else {
return a1[1].compareTo(a2[1]);
}
}
This is just a basic example, some extra error checking would be nice.
Upvotes: 5