Jeeppp
Jeeppp

Reputation: 1573

Collect from stream into a multimap

I have a phrase and I'm splitting on white space and creating a map that would hold the word and the index position of the word.

I worked fine. But the problem is when the phrases contained duplicate words. So I wanted to use com.google.common.collect.Multimap in Google Guava.

Is there a way to generate the Multimap using the below stream's collector?

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));

Upvotes: 7

Views: 5462

Answers (2)

Samuel Philipp
Samuel Philipp

Reputation: 11050

You can just use this:

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);

The result will be:

{a=[0, 5], b=[1, 6], c=[2, 7], d=[3], e=[4]}

Upvotes: 6

John Bollinger
John Bollinger

Reputation: 181714

Stream.collect() is a very general API, so there's no particular reason why one could not collect to a Multimap. But none of the variants of Collectors.toMap() can support that because a com.google.common.collect.Multimap is not a java.util.Map.

I'm not aware of an existing Collector implementation that does that job, but it should certainly be possible to write one by directly implementing Collector.

Upvotes: 1

Related Questions