Прежде всего, нужно объявить дополнительный класс. Он будет содержать элемент и считать:
class ElementWithCount {
private final String element;
private final long count;
ElementWithCount(String element, long count) {
this.element = element;
this.count = count;
}
String element() {
return element;
}
long count() {
return count;
}
}
Для вычисления count
давайте объявим дополнительную функцию:
static long getElementCount(List<String> listOfComments, String element) {
return listOfComments.stream()
.filter(comment -> comment.contains(element))
.count();
}
Так что теперь, чтобы найти результат, нам нужно преобразовать поток элементов в поток ElementWithCount
объектов, затем отсортировать этот поток по количеству, затем преобразовать его обратно в поток элементов и собрать его в список результатов.
Чтобы упростить эту задачу, давайте определим компаратор как отдельную переменную:
Comparator<ElementWithCount> comparator = Comparator
.comparing(ElementWithCount::count).reversed()
.thenComparing(ElementWithCount::element);
и теперь, когда все части готовы, окончательное вычисление легко:
List<String> result = elements.stream()
.map(element -> new ElementWithCount(element, getElementCount(listOfComments, element)))
.sorted(comparator)
.map(ElementWithCount::element)
.collect(Collectors.toList());
Вы можете использовать Map.Entry вместо отдельного класса и встроенного getElementCount
, так что Это будет «однострочное» решение:
List<String> result = elements.stream()
.map(element ->
new AbstractMap.SimpleImmutableEntry<>(element,
listOfComments.stream()
.filter(comment -> comment.contains(element))
.count()))
.sorted(Map.Entry.<String, Long>comparingByValue().reversed().thenComparing(Map.Entry.comparingByKey()))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
Но в этой форме понять гораздо сложнее, поэтому я рекомендую разбить его на логические части.