Собрать из потока в мультикарту - PullRequest
2 голосов
/ 01 мая 2019

У меня есть фраза, и я разделяю пробел и создаю карту, которая будет содержать слово и позицию индекса слова.

Я работал хорошо.Но проблема в том, что фразы содержали повторяющиеся слова.Поэтому я хотел использовать com.google.common.collect.Multimap.

Есть ли способ сгенерировать мультикарту, используя сборщик приведенного ниже потока?

List<String> words = new ArrayList<>(Arrays.asList(phrase.split("\\s+")));
Map<String, Integer> tokenMap = IntStream.range(0, words.size())
            .boxed()
            .collect(Collectors.toMap(words::get, i -> i));

Ответы [ 3 ]

0 голосов
/ 01 мая 2019

Вы можете просто использовать это:

List<String> words = Arrays.asList("a b c d e a b c".split("\\s+"));
Multimap<String, Integer> tokenMap = IntStream.range(0, words.size()).boxed()
        .collect(ArrayListMultimap::create, (m, i) -> m.put(words.get(i), i), Multimap::putAll);

Результат будет:

{a=[0, 5], b=[1, 6], c=[2, 7], d=[3], e=[4]}
0 голосов
/ 01 мая 2019

Вы можете сделать это, используя Collectors.groupingBy и AbstractMap.SimpleEntry

String phrase = "deadpool tony american tony";
    List<String> words = Arrays.asList(phrase.split("\\s+"));

    Map<String, List<Integer>> result = IntStream.range(0, words.size())
            .mapToObj(i -> new AbstractMap.SimpleEntry<>(words.get(i), i)).collect(
                    Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList())));

    System.out.println(result);    //{tony=[1, 3], deadpool=[0], american=[2]}
0 голосов
/ 01 мая 2019

Stream.collect() - это очень общий API, поэтому нет особой причины, по которой невозможно собрать в Multimap. Но ни один из вариантов Collectors.toMap() не может это поддерживать, поскольку com.google.common.collect.Multimap не является java.util.Map.

Мне не известно о существующей реализации Collector, которая выполняет эту работу, но, безусловно, должна быть возможность написать ее, напрямую внедрив Collector.

...