I am trying to get Top N values based on repetition from a list in Java.
Example: Find Top 2 values
[ "strawberries", "orange", "apple", "mango", "grapes", "pineapple", "mango", "strawberries", "mango", "apple"]
Result:
["mango"] //mango repeated 3 times
["strawberries", "apple"] // "strawberries", "apple" repeated 2 times each
I have written below code to acheive this
private static List<List<String>> getTop(int n, List<String> values) {
Map<String, Long> valueCountMap = values.stream()
.collect(groupingBy(x -> x, counting()));
final Map<String, Long> sortedByCount = valueCountMap.entrySet()
.stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));
List<List<String>> topNValues = new ArrayList<>();
long prevValue = -1;
for (Map.Entry<String, Long> e : sortedByCount.entrySet()) {
if (prevValue == -1 || prevValue != e.getValue()) {
if (topNValues.size() == n) {
break;
}
prevValue = e.getValue();
List<String> keys = new ArrayList<>();
keys.add(e.getKey());
topNValues.add(keys);
} else if (prevValue == e.getValue()) {
List<String> keys = topNValues.get(topNValues.size() - 1);
keys.add(e.getKey());
}
}
return topNValues;
}
I want to know if there is a better way of implementing this. Both performance and implementation wise.