Sort using a custom comparator that understands underscores are special:
Collections.sort(listStrings, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.startsWith("_") && o2.startsWith("_")) {
return compare(o1.substring(1), o2.substring(1));
}
if (o1.startsWith("_")) {
return 1;
}
if (o2.startsWith("_")) {
return -1;
}
return o1.compareTo(o2);
}
});
This will also handle the situation where multiple underscores are present. E.g. __foo
will be considered after _foo
.
To cope with arbitrary numbers of special characters, define them in an array (in your preferred order) and use a more advanced comparator:
Collections.sort(listStrings, new Comparator<String>() {
// declare in order of desired sort
private final String[] specialChars = { "_", ">" };
@Override
public int compare(String o1, String o2) {
/*
* CASES
*
* 1. Both start with same special char
*
* 2. Both start with a special char
*
* 3. One starts with a special char
*
* 4. None starts with a special char
*/
int o1SpecialIndex = -1;
int o2SpecialIndex = -1;
for (int i = 0; i < specialChars.length; i++) {
if (o1.startsWith(specialChars[i])) {
o1SpecialIndex = i;
}
if (o2.startsWith(specialChars[i])) {
o2SpecialIndex = i;
}
}
// case 1:
if (o1SpecialIndex != -1 && o1SpecialIndex == o2SpecialIndex) {
return compare(o1.substring(1), o2.substring(1));
}
// case 2:
if (o1SpecialIndex != -1 && o2SpecialIndex != -1) {
return o2SpecialIndex - o1SpecialIndex;
}
// case 3:
if (o1SpecialIndex != -1) {
return 1;
}
if (o2SpecialIndex != -1) {
return -1;
}
// case 4:
return o1.compareTo(o2);
}
});