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











up vote
10
down vote

favorite
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




























    up vote
    10
    down vote

    favorite
    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


























      up vote
      10
      down vote

      favorite
      2









      up vote
      10
      down vote

      favorite
      2






      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

      18.1k41838




      18.1k41838










      asked Nov 27 at 8:06









      Sergii

      2,39951847




      2,39951847
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          9
          down vote



          accepted










          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


















          up vote
          11
          down vote













          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


















          up vote
          5
          down vote













          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',
            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








            up vote
            9
            down vote



            accepted










            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















            up vote
            9
            down vote



            accepted










            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













            up vote
            9
            down vote



            accepted







            up vote
            9
            down vote



            accepted






            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

            274k35439521




            274k35439521












            • 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












            up vote
            11
            down vote













            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















            up vote
            11
            down vote













            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













            up vote
            11
            down vote










            up vote
            11
            down vote









            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

            7,91831533




            7,91831533








            • 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










            up vote
            5
            down vote













            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

























              up vote
              5
              down vote













              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























                up vote
                5
                down vote










                up vote
                5
                down vote









                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,775821




                2,775821






























                    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

                    數位音樂下載

                    When can things happen in Etherscan, such as the picture below?

                    格利澤436b