Smajl
Smajl

Reputation: 7995

How to aggregate map values into set using streams

Is there some easy way how to convert Map<Key, List<Value>> into Set<Value> to get a set of all unique elements nested int the map? I know this should be possible using reduce or flatmap but I am struggling with the right combination.

I know I could do this using for loop but I would like to perform this operation using streams.

Upvotes: 2

Views: 701

Answers (3)

iamgirdhar
iamgirdhar

Reputation: 1155

Map values in a set along with sorted data.

public class Test {
    public static void main(String[] args) {

        Map<Integer, List<String>> dataInMap = new HashMap<>();

        dataInMap.put(100, Arrays.asList("data8","data9","data3","data4","data5"));
        dataInMap.put(200, Arrays.asList("data5","data6","data7"));
        dataInMap.put(300, Arrays.asList("data7","data8","data9"));
        dataInMap.put(400, Arrays.asList("data1","data2"));

        Set<String> uniqueDataInSet = dataInMap.values()
                        .stream()
                        .flatMap(Collection::stream)
                        .sorted()
                        .collect(Collectors.toCollection(LinkedHashSet::new));
        System.out.println("uniqueDataInSet:: " + uniqueDataInSet);
      //uniqueDataInSet:: [data1, data2, data3, data4, data5, data6, data7, data8, data9]
    }
}

Thanks Girdhar

Upvotes: 0

Bishoy Awad
Bishoy Awad

Reputation: 79

First of all you have to make sure your Value class implements equals and hashCode.

I would go with the flatmap combination.

It would look like that

Set<Value> values = map.values().stream()
                                .flatMap(List::stream)
                                .collect(Collectors.toSet())

Upvotes: 4

Sorin
Sorin

Reputation: 1007

Set<Value> set = map.values().stream()
                             .flatMap(List::stream)
                             .collect(Collectors.toSet());

Set will not add a Value that is already in it, so you have to make sure, that your Value objects have a proper equals() method.


Edit: List::stream is equivalent to list -> list.stream() in functionality according to this post.

Upvotes: 5

Related Questions