i'm trying to sort a list of strings based on a custom sort order by defining some prefixes. the result should be ordered based on the order of the prefixes and the none matching entries should be at the end of the list. when multiple strings are starting with the same prefix or there are multiple entries in the rest the should be sorted alphabetically.
already tried a custom comparator based on a soltion from another thread How to sort a java list against a custom order. But i'm now stuck at the last part of my requirement to bring the remaining entries which do not have a prefix at the end of the list.
final Comparator<String> comparator = new PrefixComparator(Arrays.asList("java.", "javax.", "org."));
final ArrayList<String> imports = Lists.newArrayList("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Test", "org.testng.annotations.Optional", "de.bigmichi1.test.ClassB");
Collections.shuffle(imports);
imports.sort(comparator);
Assertions.assertThat(imports).containsExactly("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Optional","org.testng.annotations.Test", "de.bigmichi1.test.ClassB");
public class PrefixComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = -5748758614646881440L;
private final List<String> customOrder;
public PrefixComparator(@Nonnull final List<String> customOrder) {
this.customOrder = customOrder;
}
@Override
public int compare(final String o1,
final String o2) {
int order1 = -1;
int order2 = -1;
String remainder1 = "";
String remainder2 = "";
for (final String prefix : customOrder) {
if (o1.startsWith(prefix)) {
order1 = customOrder.indexOf(prefix);
remainder1 = o1.substring(prefix.length());
}
if (o2.startsWith(prefix)) {
order2 = customOrder.indexOf(prefix);
remainder2 = o2.substring(prefix.length());
}
}
if (order1 == order2) {
return remainder1.compareTo(remainder2);
} else {
return order1 - order2;
}
}
}