I think you should create a class to represent the elements in the list.
For instance:
public class WordCount {
public static final Comparator<WordCount> BY_COUNT;
private static final Pattern PATTERN
= Pattern.compile("\\s*([0-9]+)\\s+(.*)");
public final int count;
public final String word;
public static WordCount parse(String s) {
Matcher matcher = PATTERN.matcher(s);
if (!matcher.matches()) {
throw new IllegalArgumentException("Syntax error: " + s);
}
return new WordCount(
Integer.parseInt(matcher.group(1)), matcher.group(2));
}
public WordCount(int count, String word) {
this.count = count;
this.word = word;
}
@Override
public String toString() {
return count + " " + word;
}
static {
BY_COUNT = (WordCount o1, WordCount o2) -> {
int r = Integer.compare(o1.count, o2.count);
if (r == 0) {
r = o1.word.compareTo(o2.word);
}
return r;
};
}
}
Your code would then become:
List<WordCount> words = new ArrayList<>();
words.add(WordCount.parse("9 hello"));
words.add(WordCount.parse("98 food"));
words.add(WordCount.parse("105 cat"));
words.add(WordCount.parse("2514 human"));
words.add(WordCount.parse("3 pencil"));
words.sort(WordCount.BY_COUNT.reversed());
words.forEach((wc) -> {
System.out.println(wc);
});
With the following result:
2514 human
105 cat
98 food
9 hello
3 pencil
2514 humanshould be before105 cat?9...is higher than2...no matter what comes after. You need to interpret the numbers as actual numbers instead of text to sort this in the way you want.