I want to create a comparator for string values, but according to https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html underscore symbol has bigger value than any digit. Is it possible to change it somehow?
Short answer
Yes, it is. You need a custom string comparator.
Solution
Let's say you need to sort a list of strings:
[a_123, ab123, a123, 123, _123]
If you sort it using Collections.sort
then it'll be sorter in the following order:
[123, _123, a123, a_123, ab123]
But you want to override the "weight" of _
. To achieve this you need a custom string comparator. Let's copy and modify a bit java.lang.String#compareTo
:
private int customStringComparator(String s1, String s2) {
int len1 = s1.length();
int len2 = s2.length();
int lim = Math.min(len1, len2);
char v1[] = s1.toCharArray();
char v2[] = s2.toCharArray();
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
// You can add your custom comparison here:
if ('_' == c1 && Character.isDigit(c2)) {
// We intentionally return inverted result
return c2 - c1;
}else if(c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
Now we can pass our customStringComparator
to Collections.sort
:
Collections.sort(list, this::customStringComparator);
The list will be sorted in the following order:
[_123, 123, a_123, a123, ab123]
As you can see, now the _
precedes digits.
This might work:
private int compareStrings(String o1, String o2) {
if(o1.matches("\\d+") && o2.equals("_")) {
return 1;
}
if(o1.equals("_") && o2.matches("\\d+")) {
return -1;
}
return o1.compareTo(o2);
}
And then define your comparator like so:
Comparator<String> stringComparator2 = this::compareStrings;
EDIT:
According to not working for string with _
in the middle, how about just replacing _
with character that is before in ASCII table just for comparing (like " "
for example):
public static int compareStrings(String o1, String o2) {
o1 = o1.replaceAll("_", " ");
o2 = o2.replaceAll("_", " ");
return o1.compareTo(o2);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.