Convert Map to Map<String, Set> with filter and streams












20















I would like to convert my map which looks like this:



{
key="someKey1", value=Apple(id="1", color="green"),
key="someKey2", value=Apple(id="2", color="red"),
key="someKey3", value=Apple(id="3", color="green"),
key="someKey4", value=Apple(id="4", color="red"),
}


to another map which puts all apples of the same color into the same list:



{
key="red", value=list={apple1, apple3},
key="green", value=list={apple2, apple4},
}


I tried the following:



Map<String, Set<Apple>> sortedApples = appleMap.entrySet()
.stream()
.collect(Collectors.toMap(l -> l.getColour, ???));


Am I on the right track? Should I use filters for this task? Is there an easier way?










share|improve this question





























    20















    I would like to convert my map which looks like this:



    {
    key="someKey1", value=Apple(id="1", color="green"),
    key="someKey2", value=Apple(id="2", color="red"),
    key="someKey3", value=Apple(id="3", color="green"),
    key="someKey4", value=Apple(id="4", color="red"),
    }


    to another map which puts all apples of the same color into the same list:



    {
    key="red", value=list={apple1, apple3},
    key="green", value=list={apple2, apple4},
    }


    I tried the following:



    Map<String, Set<Apple>> sortedApples = appleMap.entrySet()
    .stream()
    .collect(Collectors.toMap(l -> l.getColour, ???));


    Am I on the right track? Should I use filters for this task? Is there an easier way?










    share|improve this question



























      20












      20








      20


      4






      I would like to convert my map which looks like this:



      {
      key="someKey1", value=Apple(id="1", color="green"),
      key="someKey2", value=Apple(id="2", color="red"),
      key="someKey3", value=Apple(id="3", color="green"),
      key="someKey4", value=Apple(id="4", color="red"),
      }


      to another map which puts all apples of the same color into the same list:



      {
      key="red", value=list={apple1, apple3},
      key="green", value=list={apple2, apple4},
      }


      I tried the following:



      Map<String, Set<Apple>> sortedApples = appleMap.entrySet()
      .stream()
      .collect(Collectors.toMap(l -> l.getColour, ???));


      Am I on the right track? Should I use filters for this task? Is there an easier way?










      share|improve this question
















      I would like to convert my map which looks like this:



      {
      key="someKey1", value=Apple(id="1", color="green"),
      key="someKey2", value=Apple(id="2", color="red"),
      key="someKey3", value=Apple(id="3", color="green"),
      key="someKey4", value=Apple(id="4", color="red"),
      }


      to another map which puts all apples of the same color into the same list:



      {
      key="red", value=list={apple1, apple3},
      key="green", value=list={apple2, apple4},
      }


      I tried the following:



      Map<String, Set<Apple>> sortedApples = appleMap.entrySet()
      .stream()
      .collect(Collectors.toMap(l -> l.getColour, ???));


      Am I on the right track? Should I use filters for this task? Is there an easier way?







      java lambda java-8 java-stream






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 11:47









      Aomine

      42.3k74474




      42.3k74474










      asked Jan 2 at 11:23









      M4V3NM4V3N

      15910




      15910
























          4 Answers
          4






          active

          oldest

          votes


















          10














          if you want to proceed with toMap you can get the result as follows:



          map.values()  // get the apples
          .stream() // Stream<Apple>
          .collect(toMap(Apple::getColour, // group by colour
          v -> new HashSet<>(singleton(v)), // have values as set of apples
          (l, r) -> {l.addAll(r); return l;})); // merge colliding apples by colour



          • stream over the map values instead of entrySet because we're not concerned with the map keys.


          • Apple::getColour is the keyMapper function used to extract the "thing" we wish to group by, in this case, the Apples colour.


          • v -> new HashSet<>(singleton(v)) is the valueMapper function used for the resulting map values


          • (l, r) -> {l.addAll(r); return l;} is the merge function used to combine two HashSet's when there is a key collision on the Apple's colour.

          • finally, the resulting map is a Map<String, Set<Apple>>


          but this is better with groupingBy and toSet as downstream:



          map.values().stream().collect(groupingBy(Apple::getColour, toSet()));



          • stream over the map values instead of entrySet because we're not concerned with the map keys.


          • groups the Apple's by the provided classification function i.e. Apple::getColour and then collect the values in a Set hence the toSet downstream collector.


          • finally, the resulting map is a Map<String, Set<Apple>>



          short, readable and the idiomatic approach.



          You could also do it without a stream:



          Map<String, Set<Apple>> res = new HashMap<>();
          map.values().forEach(a -> res.computeIfAbsent(a.getColour(), e -> new HashSet<>()).add(a));



          • iterate over the map values instead of entrySet because we're not concerned with the map keys.

          • if the specified key a.getColour() is not already associated with a value, attempts to compute its value using the given mapping function e -> new HashSet<>() and enters it into the map. we then add the Apple to the resulting set.

          • if the specified key a.getColour() is already associated with a value computeIfAbsent returns the existing value associated with it and then we call add(a) on the HashSet to enter the Apple into the set.

          • finally, the resulting map is a Map<String, Set<Apple>>






          share|improve this answer

































            14














            Collectors.groupingBy is more suitable than Collectors.toMap for this task (though both can be used).



            Map<String, List<Apple>> sortedApples = 
            appleMap.values()
            .stream()
            .collect(Collectors.groupingBy(Apple::getColour));


            Or, to group them into Sets use:



            Map<String, Set<Apple>> sortedApples = 
            appleMap.values()
            .stream()
            .collect(Collectors.groupingBy(Apple::getColour,
            Collectors.mapping(Function.identity(),
            Collectors.toSet())));


            or (as Aomine commented):



            Map<String, Set<Apple>> sortedApples = 
            appleMap.values()
            .stream()
            .collect(Collectors.groupingBy(Apple::getColour, Collectors.toSet()));





            share|improve this answer

































              8














              You can use Collectors.groupingBy and Collectors.toSet()



              Map<String, Set<Apple>> sortedApples = appleMap.values() // Collection<Apple>
              .stream() // Stream<Apple>
              .collect(Collectors.groupingBy(Apple::getColour, // groupBy colour
              Collectors.mapping(a -> a, Collectors.toSet()))); // collect to Set





              share|improve this answer

































                3














                You've asked how to do it with streams, yet here's another way:



                Map<String, Set<Apple>> result = new LinkedHashMap<>();
                appleMap.values().forEach(apple ->
                result.computeIfAbsent(apple.getColor(), k -> new LinkedHashSet<>()).add(apple));


                This uses Map.computeIfAbsent, which either returns the set mapped to that color or puts an empty LinkedHashSet into the map if there's nothing mapped to that color yet, then adds the apple to the set.



                EDIT: I'm using LinkedHashMap and LinkedHashSet to preserve insertion order, but could have used HashMap and HashSet, respectively.






                share|improve this answer





















                • 1





                  nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                  – Aomine
                  Jan 2 at 13:53













                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005438%2fconvert-mapstring-object-to-mapstring-setobject-with-filter-and-streams%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                10














                if you want to proceed with toMap you can get the result as follows:



                map.values()  // get the apples
                .stream() // Stream<Apple>
                .collect(toMap(Apple::getColour, // group by colour
                v -> new HashSet<>(singleton(v)), // have values as set of apples
                (l, r) -> {l.addAll(r); return l;})); // merge colliding apples by colour



                • stream over the map values instead of entrySet because we're not concerned with the map keys.


                • Apple::getColour is the keyMapper function used to extract the "thing" we wish to group by, in this case, the Apples colour.


                • v -> new HashSet<>(singleton(v)) is the valueMapper function used for the resulting map values


                • (l, r) -> {l.addAll(r); return l;} is the merge function used to combine two HashSet's when there is a key collision on the Apple's colour.

                • finally, the resulting map is a Map<String, Set<Apple>>


                but this is better with groupingBy and toSet as downstream:



                map.values().stream().collect(groupingBy(Apple::getColour, toSet()));



                • stream over the map values instead of entrySet because we're not concerned with the map keys.


                • groups the Apple's by the provided classification function i.e. Apple::getColour and then collect the values in a Set hence the toSet downstream collector.


                • finally, the resulting map is a Map<String, Set<Apple>>



                short, readable and the idiomatic approach.



                You could also do it without a stream:



                Map<String, Set<Apple>> res = new HashMap<>();
                map.values().forEach(a -> res.computeIfAbsent(a.getColour(), e -> new HashSet<>()).add(a));



                • iterate over the map values instead of entrySet because we're not concerned with the map keys.

                • if the specified key a.getColour() is not already associated with a value, attempts to compute its value using the given mapping function e -> new HashSet<>() and enters it into the map. we then add the Apple to the resulting set.

                • if the specified key a.getColour() is already associated with a value computeIfAbsent returns the existing value associated with it and then we call add(a) on the HashSet to enter the Apple into the set.

                • finally, the resulting map is a Map<String, Set<Apple>>






                share|improve this answer






























                  10














                  if you want to proceed with toMap you can get the result as follows:



                  map.values()  // get the apples
                  .stream() // Stream<Apple>
                  .collect(toMap(Apple::getColour, // group by colour
                  v -> new HashSet<>(singleton(v)), // have values as set of apples
                  (l, r) -> {l.addAll(r); return l;})); // merge colliding apples by colour



                  • stream over the map values instead of entrySet because we're not concerned with the map keys.


                  • Apple::getColour is the keyMapper function used to extract the "thing" we wish to group by, in this case, the Apples colour.


                  • v -> new HashSet<>(singleton(v)) is the valueMapper function used for the resulting map values


                  • (l, r) -> {l.addAll(r); return l;} is the merge function used to combine two HashSet's when there is a key collision on the Apple's colour.

                  • finally, the resulting map is a Map<String, Set<Apple>>


                  but this is better with groupingBy and toSet as downstream:



                  map.values().stream().collect(groupingBy(Apple::getColour, toSet()));



                  • stream over the map values instead of entrySet because we're not concerned with the map keys.


                  • groups the Apple's by the provided classification function i.e. Apple::getColour and then collect the values in a Set hence the toSet downstream collector.


                  • finally, the resulting map is a Map<String, Set<Apple>>



                  short, readable and the idiomatic approach.



                  You could also do it without a stream:



                  Map<String, Set<Apple>> res = new HashMap<>();
                  map.values().forEach(a -> res.computeIfAbsent(a.getColour(), e -> new HashSet<>()).add(a));



                  • iterate over the map values instead of entrySet because we're not concerned with the map keys.

                  • if the specified key a.getColour() is not already associated with a value, attempts to compute its value using the given mapping function e -> new HashSet<>() and enters it into the map. we then add the Apple to the resulting set.

                  • if the specified key a.getColour() is already associated with a value computeIfAbsent returns the existing value associated with it and then we call add(a) on the HashSet to enter the Apple into the set.

                  • finally, the resulting map is a Map<String, Set<Apple>>






                  share|improve this answer




























                    10












                    10








                    10







                    if you want to proceed with toMap you can get the result as follows:



                    map.values()  // get the apples
                    .stream() // Stream<Apple>
                    .collect(toMap(Apple::getColour, // group by colour
                    v -> new HashSet<>(singleton(v)), // have values as set of apples
                    (l, r) -> {l.addAll(r); return l;})); // merge colliding apples by colour



                    • stream over the map values instead of entrySet because we're not concerned with the map keys.


                    • Apple::getColour is the keyMapper function used to extract the "thing" we wish to group by, in this case, the Apples colour.


                    • v -> new HashSet<>(singleton(v)) is the valueMapper function used for the resulting map values


                    • (l, r) -> {l.addAll(r); return l;} is the merge function used to combine two HashSet's when there is a key collision on the Apple's colour.

                    • finally, the resulting map is a Map<String, Set<Apple>>


                    but this is better with groupingBy and toSet as downstream:



                    map.values().stream().collect(groupingBy(Apple::getColour, toSet()));



                    • stream over the map values instead of entrySet because we're not concerned with the map keys.


                    • groups the Apple's by the provided classification function i.e. Apple::getColour and then collect the values in a Set hence the toSet downstream collector.


                    • finally, the resulting map is a Map<String, Set<Apple>>



                    short, readable and the idiomatic approach.



                    You could also do it without a stream:



                    Map<String, Set<Apple>> res = new HashMap<>();
                    map.values().forEach(a -> res.computeIfAbsent(a.getColour(), e -> new HashSet<>()).add(a));



                    • iterate over the map values instead of entrySet because we're not concerned with the map keys.

                    • if the specified key a.getColour() is not already associated with a value, attempts to compute its value using the given mapping function e -> new HashSet<>() and enters it into the map. we then add the Apple to the resulting set.

                    • if the specified key a.getColour() is already associated with a value computeIfAbsent returns the existing value associated with it and then we call add(a) on the HashSet to enter the Apple into the set.

                    • finally, the resulting map is a Map<String, Set<Apple>>






                    share|improve this answer















                    if you want to proceed with toMap you can get the result as follows:



                    map.values()  // get the apples
                    .stream() // Stream<Apple>
                    .collect(toMap(Apple::getColour, // group by colour
                    v -> new HashSet<>(singleton(v)), // have values as set of apples
                    (l, r) -> {l.addAll(r); return l;})); // merge colliding apples by colour



                    • stream over the map values instead of entrySet because we're not concerned with the map keys.


                    • Apple::getColour is the keyMapper function used to extract the "thing" we wish to group by, in this case, the Apples colour.


                    • v -> new HashSet<>(singleton(v)) is the valueMapper function used for the resulting map values


                    • (l, r) -> {l.addAll(r); return l;} is the merge function used to combine two HashSet's when there is a key collision on the Apple's colour.

                    • finally, the resulting map is a Map<String, Set<Apple>>


                    but this is better with groupingBy and toSet as downstream:



                    map.values().stream().collect(groupingBy(Apple::getColour, toSet()));



                    • stream over the map values instead of entrySet because we're not concerned with the map keys.


                    • groups the Apple's by the provided classification function i.e. Apple::getColour and then collect the values in a Set hence the toSet downstream collector.


                    • finally, the resulting map is a Map<String, Set<Apple>>



                    short, readable and the idiomatic approach.



                    You could also do it without a stream:



                    Map<String, Set<Apple>> res = new HashMap<>();
                    map.values().forEach(a -> res.computeIfAbsent(a.getColour(), e -> new HashSet<>()).add(a));



                    • iterate over the map values instead of entrySet because we're not concerned with the map keys.

                    • if the specified key a.getColour() is not already associated with a value, attempts to compute its value using the given mapping function e -> new HashSet<>() and enters it into the map. we then add the Apple to the resulting set.

                    • if the specified key a.getColour() is already associated with a value computeIfAbsent returns the existing value associated with it and then we call add(a) on the HashSet to enter the Apple into the set.

                    • finally, the resulting map is a Map<String, Set<Apple>>







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 2 at 13:18

























                    answered Jan 2 at 11:40









                    AomineAomine

                    42.3k74474




                    42.3k74474

























                        14














                        Collectors.groupingBy is more suitable than Collectors.toMap for this task (though both can be used).



                        Map<String, List<Apple>> sortedApples = 
                        appleMap.values()
                        .stream()
                        .collect(Collectors.groupingBy(Apple::getColour));


                        Or, to group them into Sets use:



                        Map<String, Set<Apple>> sortedApples = 
                        appleMap.values()
                        .stream()
                        .collect(Collectors.groupingBy(Apple::getColour,
                        Collectors.mapping(Function.identity(),
                        Collectors.toSet())));


                        or (as Aomine commented):



                        Map<String, Set<Apple>> sortedApples = 
                        appleMap.values()
                        .stream()
                        .collect(Collectors.groupingBy(Apple::getColour, Collectors.toSet()));





                        share|improve this answer






























                          14














                          Collectors.groupingBy is more suitable than Collectors.toMap for this task (though both can be used).



                          Map<String, List<Apple>> sortedApples = 
                          appleMap.values()
                          .stream()
                          .collect(Collectors.groupingBy(Apple::getColour));


                          Or, to group them into Sets use:



                          Map<String, Set<Apple>> sortedApples = 
                          appleMap.values()
                          .stream()
                          .collect(Collectors.groupingBy(Apple::getColour,
                          Collectors.mapping(Function.identity(),
                          Collectors.toSet())));


                          or (as Aomine commented):



                          Map<String, Set<Apple>> sortedApples = 
                          appleMap.values()
                          .stream()
                          .collect(Collectors.groupingBy(Apple::getColour, Collectors.toSet()));





                          share|improve this answer




























                            14












                            14








                            14







                            Collectors.groupingBy is more suitable than Collectors.toMap for this task (though both can be used).



                            Map<String, List<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour));


                            Or, to group them into Sets use:



                            Map<String, Set<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour,
                            Collectors.mapping(Function.identity(),
                            Collectors.toSet())));


                            or (as Aomine commented):



                            Map<String, Set<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour, Collectors.toSet()));





                            share|improve this answer















                            Collectors.groupingBy is more suitable than Collectors.toMap for this task (though both can be used).



                            Map<String, List<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour));


                            Or, to group them into Sets use:



                            Map<String, Set<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour,
                            Collectors.mapping(Function.identity(),
                            Collectors.toSet())));


                            or (as Aomine commented):



                            Map<String, Set<Apple>> sortedApples = 
                            appleMap.values()
                            .stream()
                            .collect(Collectors.groupingBy(Apple::getColour, Collectors.toSet()));






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jan 2 at 12:20

























                            answered Jan 2 at 11:27









                            EranEran

                            288k37468558




                            288k37468558























                                8














                                You can use Collectors.groupingBy and Collectors.toSet()



                                Map<String, Set<Apple>> sortedApples = appleMap.values() // Collection<Apple>
                                .stream() // Stream<Apple>
                                .collect(Collectors.groupingBy(Apple::getColour, // groupBy colour
                                Collectors.mapping(a -> a, Collectors.toSet()))); // collect to Set





                                share|improve this answer






























                                  8














                                  You can use Collectors.groupingBy and Collectors.toSet()



                                  Map<String, Set<Apple>> sortedApples = appleMap.values() // Collection<Apple>
                                  .stream() // Stream<Apple>
                                  .collect(Collectors.groupingBy(Apple::getColour, // groupBy colour
                                  Collectors.mapping(a -> a, Collectors.toSet()))); // collect to Set





                                  share|improve this answer




























                                    8












                                    8








                                    8







                                    You can use Collectors.groupingBy and Collectors.toSet()



                                    Map<String, Set<Apple>> sortedApples = appleMap.values() // Collection<Apple>
                                    .stream() // Stream<Apple>
                                    .collect(Collectors.groupingBy(Apple::getColour, // groupBy colour
                                    Collectors.mapping(a -> a, Collectors.toSet()))); // collect to Set





                                    share|improve this answer















                                    You can use Collectors.groupingBy and Collectors.toSet()



                                    Map<String, Set<Apple>> sortedApples = appleMap.values() // Collection<Apple>
                                    .stream() // Stream<Apple>
                                    .collect(Collectors.groupingBy(Apple::getColour, // groupBy colour
                                    Collectors.mapping(a -> a, Collectors.toSet()))); // collect to Set






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Jan 2 at 11:41

























                                    answered Jan 2 at 11:27









                                    NamanNaman

                                    44.1k11102202




                                    44.1k11102202























                                        3














                                        You've asked how to do it with streams, yet here's another way:



                                        Map<String, Set<Apple>> result = new LinkedHashMap<>();
                                        appleMap.values().forEach(apple ->
                                        result.computeIfAbsent(apple.getColor(), k -> new LinkedHashSet<>()).add(apple));


                                        This uses Map.computeIfAbsent, which either returns the set mapped to that color or puts an empty LinkedHashSet into the map if there's nothing mapped to that color yet, then adds the apple to the set.



                                        EDIT: I'm using LinkedHashMap and LinkedHashSet to preserve insertion order, but could have used HashMap and HashSet, respectively.






                                        share|improve this answer





















                                        • 1





                                          nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                          – Aomine
                                          Jan 2 at 13:53


















                                        3














                                        You've asked how to do it with streams, yet here's another way:



                                        Map<String, Set<Apple>> result = new LinkedHashMap<>();
                                        appleMap.values().forEach(apple ->
                                        result.computeIfAbsent(apple.getColor(), k -> new LinkedHashSet<>()).add(apple));


                                        This uses Map.computeIfAbsent, which either returns the set mapped to that color or puts an empty LinkedHashSet into the map if there's nothing mapped to that color yet, then adds the apple to the set.



                                        EDIT: I'm using LinkedHashMap and LinkedHashSet to preserve insertion order, but could have used HashMap and HashSet, respectively.






                                        share|improve this answer





















                                        • 1





                                          nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                          – Aomine
                                          Jan 2 at 13:53
















                                        3












                                        3








                                        3







                                        You've asked how to do it with streams, yet here's another way:



                                        Map<String, Set<Apple>> result = new LinkedHashMap<>();
                                        appleMap.values().forEach(apple ->
                                        result.computeIfAbsent(apple.getColor(), k -> new LinkedHashSet<>()).add(apple));


                                        This uses Map.computeIfAbsent, which either returns the set mapped to that color or puts an empty LinkedHashSet into the map if there's nothing mapped to that color yet, then adds the apple to the set.



                                        EDIT: I'm using LinkedHashMap and LinkedHashSet to preserve insertion order, but could have used HashMap and HashSet, respectively.






                                        share|improve this answer















                                        You've asked how to do it with streams, yet here's another way:



                                        Map<String, Set<Apple>> result = new LinkedHashMap<>();
                                        appleMap.values().forEach(apple ->
                                        result.computeIfAbsent(apple.getColor(), k -> new LinkedHashSet<>()).add(apple));


                                        This uses Map.computeIfAbsent, which either returns the set mapped to that color or puts an empty LinkedHashSet into the map if there's nothing mapped to that color yet, then adds the apple to the set.



                                        EDIT: I'm using LinkedHashMap and LinkedHashSet to preserve insertion order, but could have used HashMap and HashSet, respectively.







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Jan 2 at 13:55

























                                        answered Jan 2 at 13:50









                                        Federico Peralta SchaffnerFederico Peralta Schaffner

                                        23.4k43677




                                        23.4k43677








                                        • 1





                                          nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                          – Aomine
                                          Jan 2 at 13:53
















                                        • 1





                                          nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                          – Aomine
                                          Jan 2 at 13:53










                                        1




                                        1





                                        nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                        – Aomine
                                        Jan 2 at 13:53







                                        nice! +1, it would be better to iterate over the map values though since you're not doing anything with the key, i.e. appleMap.values().forEach(apple -> result.computeIfAbsent(apple.getColour(), k -> new LinkedHashSet<>()).add(apple));

                                        – Aomine
                                        Jan 2 at 13:53




















                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005438%2fconvert-mapstring-object-to-mapstring-setobject-with-filter-and-streams%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Mossoró

                                        Error while reading .h5 file using the rhdf5 package in R

                                        Pushsharp Apns notification error: 'InvalidToken'