问题
I'm trying to sort an ArrayList which a series of String composed as well (XX and YY are numbers):
Test: XX Genere: Maschio Eta: YY Protocollo: A
I would link to sort them by only considering the YY value. I found this method but it considerers all the digits of the string and I cannot remove n digits before YY because I don't know from how many digits is composed XX:
Collections.sort(strings, new Comparator<String>() {
public int compare(String o1, String o2) {
return extractInt(o1) - extractInt(o2);
}
int extractInt(String s) {
String num = s.replaceAll("\\D", "");
// return 0 if no digits found
return num.isEmpty() ? 0 : Integer.parseInt(num);
}
});
回答1:
You also need to come up with how you'd like to sort the strings that don't have a number in the second part.
Collections.sort(strings, new Comparator<String>() {
public int compare(String o1, String o2) {
return Comparator.comparingInt(this::extractInt)
.thenComparing(Comparator.naturalOrder())
.compare(o1, o2);
}
private int extractInt(String s) {
try {
return Integer.parseInt(s.split(":")[1].trim());
}
catch (NumberFormatException exception) {
// if the given String has no number in the second part,
// I treat such Strings equally, and compare them naturally later
return -1;
}
}
});
UPDATE
If you are sure Integer.parseInt(s.split(":")[1].trim())
never fails with an exception, Comparator.comparingInt(this::extractInt)
would be enough, and you could go with a shorter comparator.
Collections.sort(strings,
Comparator.comparingInt(s -> Integer.parseInt(s.split(":")[1].trim())));
回答2:
YY seems to be the second number in the string, so you can extract it with the regex \d+
and calling Matcher.find()
twice.
// assuming extractInt is declared in "YourClass"
static int extractInt(String s) {
Matcher m = Pattern.compile("\\d+").matcher(s);
m.find();
if (m.find()) {
return Integer.parserInt(m.group());
} else {
return 0;
}
}
// ...
Collections.sort(strings, Comparator.comparingInt(YourClass::extractInt));
You should also consider the approach of first parsing all the strings into a list of instances of a class like this:
class MyObject {
private int test;
private String genere;
private int eta;
private int protocollo;
// getters and constructor...
}
And then you can simply use Comparator.comparingInt(MyObject::getEta)
as the comparator.
回答3:
One way to compare them is to find the substring "Eta: " and compare the strings from it's position:
Collections.sort(strings, (String s1, String s2) -> s1.substring((s1.indexOf("Eta: "))).
compareTo(s2.substring((s2.indexOf("Eta: ")))));
来源:https://stackoverflow.com/questions/57605015/sort-arrayliststring-excluding-the-digits-on-the-first-half-of-the-string