The java by default sorting is based on either number or string. If we try to sort a alphaneumeric it will be treated as an string so the sorting will come something like:
1abc
11abc
2abc
instead of
1abc
2abc
11abc
So in such cases we can use our own comparator based on regex, code is given below:
import java.math.BigInteger;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CompareNumberBasedString implements Comparator<CharSequence> {
private static final Pattern PATTERN = Pattern.compile("(\\D*)(\\d*)");
public int compare(CharSequence c1, CharSequence c2) {
Matcher matcher1 = PATTERN.matcher(c1);
Matcher matcher2 = PATTERN.matcher(c2);
// The only way find() could fail is at the end of a string
while (matcher1.find() && matcher2.find()) {
//non digit comparison
int nonDigitCompare = matcher1.group(1).compareTo(matcher2.group(1));
if (0 != nonDigitCompare) {
return nonDigitCompare;
}
// digit comparison
if (matcher1.group(2).isEmpty()) {
return matcher2.group(2).isEmpty() ? 0 : -1;
} else if (matcher2.group(2).isEmpty()) {
return +1;
}
BigInteger number1 = new BigInteger(matcher1.group(2));
BigInteger number2 = new BigInteger(matcher2.group(2));
int numberCompare = number1.compareTo(number2);
if (0 != numberCompare) {
return numberCompare;
}
}
// Handle if one string is a prefix of the other.
return matcher1.hitEnd() && matcher2.hitEnd() ? 0 :
matcher1.hitEnd() ? -1 : +1;
}
}
0 Comment(s)