Сопоставление строкового представления каждой строки с учетом списка списков строк с ее общим количеством вхождений

Позвольте мне сначала более точно описать задание. Даны следующий класс и внутренний класс:

public class Title {

    private List<Line> lines;

    public Title() {
        this(new ArrayList<>());
    }

    public Title(List<Line> lines) {
        this.lines = lines;
    }

    public void add(Line l) {
        lines.add(l);
    }

    @Override
    public String toString() {
        return lines.toString();
    }

    public List<Line> getLines() {
        return new ArrayList<>(lines);
    }
public  class Line {

    private String line;

    public Line(String line) {
        this.line = line;
    }

    @Override
    public String toString() {
        return line;
    }
}

Предположим, у нас есть List<Title> titles. Задача состоит в том, чтобы получить карту из строкового представления каждой строки с ее общим количеством вхождений вtitles. В качестве подсказки указано, чтоflatMap необходимо и что есть решение с Collectors.toMap и один с Collectors.groupingBy.

Я придумал первое, но я очень опасаюсь, что он излишне запутан. Как я мог это улучшить? Вот:

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.flatMapping;
import static java.util.Collections.frequency;

Map<String, Integer> countsStringMap1 = titles.stream()
                                              .flatMap(t-> t.getLines().stream().map(Line::toString))
                                              .distinct()
                                              .collect(toMap(Function.identity(),
                                                          s -> frequency(titles.stream()
                                                                               .flatMap(t-> t.getLines()
                                                                                             .stream()
                                                                                             .map(Line::toString))
                                                                                             .collect(toList()), s)));

Я не мог найти решения с groupingBy, Я пробовал комбинацию с Collectors.mapping но безрезультатно.

Как это сделать?

1 ответ

Решение

Вы можете использовать counting подсчитать количество вхождений, когда вы groupBy строки по их строковому представлению.

Map<String, Long> countsStringMap = titles.stream()
        .flatMap(t -> t.getLines().stream().map(Title.Line::toString))
        .collect(Collectors.groupingBy(Function.identity(),
                Collectors.counting()));

Обратите внимание, что distinct Операция удаляется в решении намеренно, поскольку в противном случае у вас останутся все отдельные строки, прежде чем вы сгруппируете их и в конечном итоге подсчитаете каждую из них только один раз.

Другие вопросы по тегам