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