Java 8 Collectors.groupingBy with mapped value to set collecting result to the same set












13














Objects are used in example are from package org.jsoup.nodes



import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


I need group attributes by key with resulting value Set.



Optional<Element> buttonOpt = ...;
Map<String, Set<String>> stringStringMap =
buttonOpt.map(button -> button.attributes().asList().stream()
.collect(groupingBy(Attribute::getKey,
mapping(attribute -> attribute.getValue(), toSet()))))
.orElse(new HashMap<>());


It seems collected correctly, but value all the time is single string (because of library implementation) that contains different values split by space. Trying to improve solution:



Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
button -> button.attributes()
.asList()
.stream()
.collect(groupingBy(Attribute::getKey,
mapping(attribute ->
new HashSet<String>(Arrays.asList(attribute.getValue()
.split(" "))),
toSet()))))
.orElse(new HashMap<>());


In result i've got different structure Map<String, Set<HashSet<String>>> but i need Map<String, Set<String>>



I've checked some collectors but have not managed my issue.



Question is:



How to merge all sets that related to the same attribute key?










share|improve this question





























    13














    Objects are used in example are from package org.jsoup.nodes



    import org.jsoup.nodes.Attribute;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;


    I need group attributes by key with resulting value Set.



    Optional<Element> buttonOpt = ...;
    Map<String, Set<String>> stringStringMap =
    buttonOpt.map(button -> button.attributes().asList().stream()
    .collect(groupingBy(Attribute::getKey,
    mapping(attribute -> attribute.getValue(), toSet()))))
    .orElse(new HashMap<>());


    It seems collected correctly, but value all the time is single string (because of library implementation) that contains different values split by space. Trying to improve solution:



    Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
    button -> button.attributes()
    .asList()
    .stream()
    .collect(groupingBy(Attribute::getKey,
    mapping(attribute ->
    new HashSet<String>(Arrays.asList(attribute.getValue()
    .split(" "))),
    toSet()))))
    .orElse(new HashMap<>());


    In result i've got different structure Map<String, Set<HashSet<String>>> but i need Map<String, Set<String>>



    I've checked some collectors but have not managed my issue.



    Question is:



    How to merge all sets that related to the same attribute key?










    share|improve this question



























      13












      13








      13


      2





      Objects are used in example are from package org.jsoup.nodes



      import org.jsoup.nodes.Attribute;
      import org.jsoup.nodes.Element;
      import org.jsoup.select.Elements;


      I need group attributes by key with resulting value Set.



      Optional<Element> buttonOpt = ...;
      Map<String, Set<String>> stringStringMap =
      buttonOpt.map(button -> button.attributes().asList().stream()
      .collect(groupingBy(Attribute::getKey,
      mapping(attribute -> attribute.getValue(), toSet()))))
      .orElse(new HashMap<>());


      It seems collected correctly, but value all the time is single string (because of library implementation) that contains different values split by space. Trying to improve solution:



      Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
      button -> button.attributes()
      .asList()
      .stream()
      .collect(groupingBy(Attribute::getKey,
      mapping(attribute ->
      new HashSet<String>(Arrays.asList(attribute.getValue()
      .split(" "))),
      toSet()))))
      .orElse(new HashMap<>());


      In result i've got different structure Map<String, Set<HashSet<String>>> but i need Map<String, Set<String>>



      I've checked some collectors but have not managed my issue.



      Question is:



      How to merge all sets that related to the same attribute key?










      share|improve this question















      Objects are used in example are from package org.jsoup.nodes



      import org.jsoup.nodes.Attribute;
      import org.jsoup.nodes.Element;
      import org.jsoup.select.Elements;


      I need group attributes by key with resulting value Set.



      Optional<Element> buttonOpt = ...;
      Map<String, Set<String>> stringStringMap =
      buttonOpt.map(button -> button.attributes().asList().stream()
      .collect(groupingBy(Attribute::getKey,
      mapping(attribute -> attribute.getValue(), toSet()))))
      .orElse(new HashMap<>());


      It seems collected correctly, but value all the time is single string (because of library implementation) that contains different values split by space. Trying to improve solution:



      Map<String, Set<HashSet<String>>> stringSetMap = buttonOpt.map(
      button -> button.attributes()
      .asList()
      .stream()
      .collect(groupingBy(Attribute::getKey,
      mapping(attribute ->
      new HashSet<String>(Arrays.asList(attribute.getValue()
      .split(" "))),
      toSet()))))
      .orElse(new HashMap<>());


      In result i've got different structure Map<String, Set<HashSet<String>>> but i need Map<String, Set<String>>



      I've checked some collectors but have not managed my issue.



      Question is:



      How to merge all sets that related to the same attribute key?







      java lambda java-8 java-stream collectors






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 27 at 8:14









      ernest_k

      19.9k42043




      19.9k42043










      asked Nov 27 at 8:06









      Sergii

      2,45451950




      2,45451950
























          3 Answers
          3






          active

          oldest

          votes


















          10














          You can split your attributes with flatMap and create new entries to group:



          Optional<Element> buttonOpt = ...
          Map<String, Set<String>> stringStringMap =
          buttonOpt.map(button ->
          button.attributes()
          .asList()
          .stream()
          .flatMap(at -> Arrays.stream(at.getValue().split(" "))
          .map(v -> new SimpleEntry<>(at.getKey(),v)))
          .collect(groupingBy(Map.Entry::getKey,
          mapping(Map.Entry::getValue, toSet()))))
          .orElse(new HashMap<>());





          share|improve this answer























          • What's at.getKey, might be a typo there with a missing ()
            – nullpointer
            Nov 27 at 9:12












          • @nullpointer it should be at.getKey(). thanks
            – Eran
            Nov 27 at 9:13






          • 2




            I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
            – Holger
            Nov 27 at 10:39



















          11














          Here's a Java9 way of doing it,



          Map<String, Set<String>> stringSetMap = buttonOpt
          .map(button -> button.attributes().asList().stream()
          .collect(Collectors.groupingBy(Attribute::getKey, Collectors.flatMapping(
          attribute -> Arrays.stream(attribute.getValue().split(" ")), Collectors.toSet()))))
          .orElse(Collections.emptyMap());





          share|improve this answer



















          • 3




            Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
            – Tomasz Linkowski
            Nov 27 at 8:50






          • 2




            orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
            – nullpointer
            Nov 27 at 9:09












          • @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
            – Tomasz Linkowski
            Nov 27 at 9:24










          • @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
            – nullpointer
            Nov 27 at 9:31










          • @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
            – Tomasz Linkowski
            Nov 27 at 9:47



















          5














          This becomes less complicated if you use a more suitable data structure for it, namely a multimap.



          Multimaps are present e.g. in Guava, where you can do this as follows:



          SetMultimap<String, String> stringMultimap = buttonOpt
          .map(button -> button.attributes().asList().stream()
          .collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
          Attribute::getKey,
          attribute -> Arrays.stream(attribute.getValue().split(" "))
          ))
          ).orElse(ImmutableSetMultimap.of());


          I made it immutable (ImmutableSetMultimap), but a mutable version can also be obtained using Multimaps.flatteningToMultimap.






          share|improve this answer





















            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%2f53495212%2fjava-8-collectors-groupingby-with-mapped-value-to-set-collecting-result-to-the-s%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            10














            You can split your attributes with flatMap and create new entries to group:



            Optional<Element> buttonOpt = ...
            Map<String, Set<String>> stringStringMap =
            buttonOpt.map(button ->
            button.attributes()
            .asList()
            .stream()
            .flatMap(at -> Arrays.stream(at.getValue().split(" "))
            .map(v -> new SimpleEntry<>(at.getKey(),v)))
            .collect(groupingBy(Map.Entry::getKey,
            mapping(Map.Entry::getValue, toSet()))))
            .orElse(new HashMap<>());





            share|improve this answer























            • What's at.getKey, might be a typo there with a missing ()
              – nullpointer
              Nov 27 at 9:12












            • @nullpointer it should be at.getKey(). thanks
              – Eran
              Nov 27 at 9:13






            • 2




              I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
              – Holger
              Nov 27 at 10:39
















            10














            You can split your attributes with flatMap and create new entries to group:



            Optional<Element> buttonOpt = ...
            Map<String, Set<String>> stringStringMap =
            buttonOpt.map(button ->
            button.attributes()
            .asList()
            .stream()
            .flatMap(at -> Arrays.stream(at.getValue().split(" "))
            .map(v -> new SimpleEntry<>(at.getKey(),v)))
            .collect(groupingBy(Map.Entry::getKey,
            mapping(Map.Entry::getValue, toSet()))))
            .orElse(new HashMap<>());





            share|improve this answer























            • What's at.getKey, might be a typo there with a missing ()
              – nullpointer
              Nov 27 at 9:12












            • @nullpointer it should be at.getKey(). thanks
              – Eran
              Nov 27 at 9:13






            • 2




              I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
              – Holger
              Nov 27 at 10:39














            10












            10








            10






            You can split your attributes with flatMap and create new entries to group:



            Optional<Element> buttonOpt = ...
            Map<String, Set<String>> stringStringMap =
            buttonOpt.map(button ->
            button.attributes()
            .asList()
            .stream()
            .flatMap(at -> Arrays.stream(at.getValue().split(" "))
            .map(v -> new SimpleEntry<>(at.getKey(),v)))
            .collect(groupingBy(Map.Entry::getKey,
            mapping(Map.Entry::getValue, toSet()))))
            .orElse(new HashMap<>());





            share|improve this answer














            You can split your attributes with flatMap and create new entries to group:



            Optional<Element> buttonOpt = ...
            Map<String, Set<String>> stringStringMap =
            buttonOpt.map(button ->
            button.attributes()
            .asList()
            .stream()
            .flatMap(at -> Arrays.stream(at.getValue().split(" "))
            .map(v -> new SimpleEntry<>(at.getKey(),v)))
            .collect(groupingBy(Map.Entry::getKey,
            mapping(Map.Entry::getValue, toSet()))))
            .orElse(new HashMap<>());






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 27 at 9:13

























            answered Nov 27 at 8:16









            Eran

            279k37449535




            279k37449535












            • What's at.getKey, might be a typo there with a missing ()
              – nullpointer
              Nov 27 at 9:12












            • @nullpointer it should be at.getKey(). thanks
              – Eran
              Nov 27 at 9:13






            • 2




              I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
              – Holger
              Nov 27 at 10:39


















            • What's at.getKey, might be a typo there with a missing ()
              – nullpointer
              Nov 27 at 9:12












            • @nullpointer it should be at.getKey(). thanks
              – Eran
              Nov 27 at 9:13






            • 2




              I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
              – Holger
              Nov 27 at 10:39
















            What's at.getKey, might be a typo there with a missing ()
            – nullpointer
            Nov 27 at 9:12






            What's at.getKey, might be a typo there with a missing ()
            – nullpointer
            Nov 27 at 9:12














            @nullpointer it should be at.getKey(). thanks
            – Eran
            Nov 27 at 9:13




            @nullpointer it should be at.getKey(). thanks
            – Eran
            Nov 27 at 9:13




            2




            2




            I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
            – Holger
            Nov 27 at 10:39




            I suggest using orElse(Collections.emptyMap()) instead, as there is no need to instantiate a new HashMap (and the groupingBy collector without a map supplier doesn’t guaranty to produce a HashMap, so the caller should not assume it).
            – Holger
            Nov 27 at 10:39













            11














            Here's a Java9 way of doing it,



            Map<String, Set<String>> stringSetMap = buttonOpt
            .map(button -> button.attributes().asList().stream()
            .collect(Collectors.groupingBy(Attribute::getKey, Collectors.flatMapping(
            attribute -> Arrays.stream(attribute.getValue().split(" ")), Collectors.toSet()))))
            .orElse(Collections.emptyMap());





            share|improve this answer



















            • 3




              Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
              – Tomasz Linkowski
              Nov 27 at 8:50






            • 2




              orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
              – nullpointer
              Nov 27 at 9:09












            • @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
              – Tomasz Linkowski
              Nov 27 at 9:24










            • @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
              – nullpointer
              Nov 27 at 9:31










            • @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
              – Tomasz Linkowski
              Nov 27 at 9:47
















            11














            Here's a Java9 way of doing it,



            Map<String, Set<String>> stringSetMap = buttonOpt
            .map(button -> button.attributes().asList().stream()
            .collect(Collectors.groupingBy(Attribute::getKey, Collectors.flatMapping(
            attribute -> Arrays.stream(attribute.getValue().split(" ")), Collectors.toSet()))))
            .orElse(Collections.emptyMap());





            share|improve this answer



















            • 3




              Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
              – Tomasz Linkowski
              Nov 27 at 8:50






            • 2




              orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
              – nullpointer
              Nov 27 at 9:09












            • @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
              – Tomasz Linkowski
              Nov 27 at 9:24










            • @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
              – nullpointer
              Nov 27 at 9:31










            • @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
              – Tomasz Linkowski
              Nov 27 at 9:47














            11












            11








            11






            Here's a Java9 way of doing it,



            Map<String, Set<String>> stringSetMap = buttonOpt
            .map(button -> button.attributes().asList().stream()
            .collect(Collectors.groupingBy(Attribute::getKey, Collectors.flatMapping(
            attribute -> Arrays.stream(attribute.getValue().split(" ")), Collectors.toSet()))))
            .orElse(Collections.emptyMap());





            share|improve this answer














            Here's a Java9 way of doing it,



            Map<String, Set<String>> stringSetMap = buttonOpt
            .map(button -> button.attributes().asList().stream()
            .collect(Collectors.groupingBy(Attribute::getKey, Collectors.flatMapping(
            attribute -> Arrays.stream(attribute.getValue().split(" ")), Collectors.toSet()))))
            .orElse(Collections.emptyMap());






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 27 at 11:32

























            answered Nov 27 at 8:23









            Ravindra Ranwala

            8,32731634




            8,32731634








            • 3




              Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
              – Tomasz Linkowski
              Nov 27 at 8:50






            • 2




              orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
              – nullpointer
              Nov 27 at 9:09












            • @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
              – Tomasz Linkowski
              Nov 27 at 9:24










            • @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
              – nullpointer
              Nov 27 at 9:31










            • @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
              – Tomasz Linkowski
              Nov 27 at 9:47














            • 3




              Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
              – Tomasz Linkowski
              Nov 27 at 8:50






            • 2




              orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
              – nullpointer
              Nov 27 at 9:09












            • @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
              – Tomasz Linkowski
              Nov 27 at 9:24










            • @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
              – nullpointer
              Nov 27 at 9:31










            • @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
              – Tomasz Linkowski
              Nov 27 at 9:47








            3




            3




            Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
            – Tomasz Linkowski
            Nov 27 at 8:50




            Nice! I'd only suggest orElseGet(HashMap::new) instead of orElse(new HashMap<>()) to make it a little bit cleaner.
            – Tomasz Linkowski
            Nov 27 at 8:50




            2




            2




            orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
            – nullpointer
            Nov 27 at 9:09






            orElse(HashMap::new) wouldn't compiler either...made an edit for the same.
            – nullpointer
            Nov 27 at 9:09














            @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
            – Tomasz Linkowski
            Nov 27 at 9:24




            @nullpointer It was supposed to be orElseGet instead of orElse. I made the proper edit.
            – Tomasz Linkowski
            Nov 27 at 9:24












            @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
            – nullpointer
            Nov 27 at 9:31




            @TomaszLinkowski Well for an initialization of a HashMap I don't think orElse and orElseGet would make difference. But still, both of them should execute just fine.
            – nullpointer
            Nov 27 at 9:31












            @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
            – Tomasz Linkowski
            Nov 27 at 9:47




            @nullpointer It's just for readability. In terms of execution, the difference is most likely insignificant.
            – Tomasz Linkowski
            Nov 27 at 9:47











            5














            This becomes less complicated if you use a more suitable data structure for it, namely a multimap.



            Multimaps are present e.g. in Guava, where you can do this as follows:



            SetMultimap<String, String> stringMultimap = buttonOpt
            .map(button -> button.attributes().asList().stream()
            .collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
            Attribute::getKey,
            attribute -> Arrays.stream(attribute.getValue().split(" "))
            ))
            ).orElse(ImmutableSetMultimap.of());


            I made it immutable (ImmutableSetMultimap), but a mutable version can also be obtained using Multimaps.flatteningToMultimap.






            share|improve this answer


























              5














              This becomes less complicated if you use a more suitable data structure for it, namely a multimap.



              Multimaps are present e.g. in Guava, where you can do this as follows:



              SetMultimap<String, String> stringMultimap = buttonOpt
              .map(button -> button.attributes().asList().stream()
              .collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
              Attribute::getKey,
              attribute -> Arrays.stream(attribute.getValue().split(" "))
              ))
              ).orElse(ImmutableSetMultimap.of());


              I made it immutable (ImmutableSetMultimap), but a mutable version can also be obtained using Multimaps.flatteningToMultimap.






              share|improve this answer
























                5












                5








                5






                This becomes less complicated if you use a more suitable data structure for it, namely a multimap.



                Multimaps are present e.g. in Guava, where you can do this as follows:



                SetMultimap<String, String> stringMultimap = buttonOpt
                .map(button -> button.attributes().asList().stream()
                .collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
                Attribute::getKey,
                attribute -> Arrays.stream(attribute.getValue().split(" "))
                ))
                ).orElse(ImmutableSetMultimap.of());


                I made it immutable (ImmutableSetMultimap), but a mutable version can also be obtained using Multimaps.flatteningToMultimap.






                share|improve this answer












                This becomes less complicated if you use a more suitable data structure for it, namely a multimap.



                Multimaps are present e.g. in Guava, where you can do this as follows:



                SetMultimap<String, String> stringMultimap = buttonOpt
                .map(button -> button.attributes().asList().stream()
                .collect(ImmutableSetMultimap.flatteningToImmutableSetMultimap(
                Attribute::getKey,
                attribute -> Arrays.stream(attribute.getValue().split(" "))
                ))
                ).orElse(ImmutableSetMultimap.of());


                I made it immutable (ImmutableSetMultimap), but a mutable version can also be obtained using Multimaps.flatteningToMultimap.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 27 at 8:24









                Tomasz Linkowski

                2,830821




                2,830821






























                    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.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • 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%2f53495212%2fjava-8-collectors-groupingby-with-mapped-value-to-set-collecting-result-to-the-s%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

                    Bundesstraße 106

                    Verónica Boquete

                    Ida-Boy-Ed-Garten