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

      41.8k74071




      41.8k74071










      asked Jan 2 at 11:23









      M4V3NM4V3N

      1259




      1259
























          4 Answers
          4






          active

          oldest

          votes


















          9














          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

































              10














              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

































                4














                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









                9














                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






























                  9














                  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




























                    9












                    9








                    9







                    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

                    41.8k74071




                    41.8k74071

























                        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

                            281k37455541




                            281k37455541























                                10














                                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






























                                  10














                                  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




























                                    10












                                    10








                                    10







                                    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









                                    nullpointernullpointer

                                    45.2k1096184




                                    45.2k1096184























                                        4














                                        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


















                                        4














                                        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
















                                        4












                                        4








                                        4







                                        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

                                        22.2k43572




                                        22.2k43572








                                        • 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

                                        MongoDB - Not Authorized To Execute Command

                                        How to fix TextFormField cause rebuild widget in Flutter

                                        in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith