Partitioning a Map in Java 8+

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












18















I have a Map<String, String> and a List<String>. I'd like to partition the Map based on the condition



foreach(map.key -> list.contains(map.key))


and produce two Map(s). What's the most elegant way to do so? I'm on Java 11, so you can throw everything you want in the answers.



What I came up to for now is:



map.entrySet()
.stream()
.collect(partitioningBy(e -> list.contains(o.getKey())));


but that gives a Map<Boolean, List<Entry<String, String>>>.










share|improve this question
























  • Please read stackoverflow.com/questions/27993604/…

    – Torben
    Feb 6 at 9:09






  • 3





    Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

    – GhostCat
    Feb 6 at 9:16















18















I have a Map<String, String> and a List<String>. I'd like to partition the Map based on the condition



foreach(map.key -> list.contains(map.key))


and produce two Map(s). What's the most elegant way to do so? I'm on Java 11, so you can throw everything you want in the answers.



What I came up to for now is:



map.entrySet()
.stream()
.collect(partitioningBy(e -> list.contains(o.getKey())));


but that gives a Map<Boolean, List<Entry<String, String>>>.










share|improve this question
























  • Please read stackoverflow.com/questions/27993604/…

    – Torben
    Feb 6 at 9:09






  • 3





    Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

    – GhostCat
    Feb 6 at 9:16













18












18








18


3






I have a Map<String, String> and a List<String>. I'd like to partition the Map based on the condition



foreach(map.key -> list.contains(map.key))


and produce two Map(s). What's the most elegant way to do so? I'm on Java 11, so you can throw everything you want in the answers.



What I came up to for now is:



map.entrySet()
.stream()
.collect(partitioningBy(e -> list.contains(o.getKey())));


but that gives a Map<Boolean, List<Entry<String, String>>>.










share|improve this question
















I have a Map<String, String> and a List<String>. I'd like to partition the Map based on the condition



foreach(map.key -> list.contains(map.key))


and produce two Map(s). What's the most elegant way to do so? I'm on Java 11, so you can throw everything you want in the answers.



What I came up to for now is:



map.entrySet()
.stream()
.collect(partitioningBy(e -> list.contains(o.getKey())));


but that gives a Map<Boolean, List<Entry<String, String>>>.







java java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 6 at 16:00









John Kugelman

244k54406457




244k54406457










asked Feb 6 at 9:07









LppEddLppEdd

4,49921545




4,49921545












  • Please read stackoverflow.com/questions/27993604/…

    – Torben
    Feb 6 at 9:09






  • 3





    Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

    – GhostCat
    Feb 6 at 9:16

















  • Please read stackoverflow.com/questions/27993604/…

    – Torben
    Feb 6 at 9:09






  • 3





    Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

    – GhostCat
    Feb 6 at 9:16
















Please read stackoverflow.com/questions/27993604/…

– Torben
Feb 6 at 9:09





Please read stackoverflow.com/questions/27993604/…

– Torben
Feb 6 at 9:09




3




3





Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

– GhostCat
Feb 6 at 9:16





Could you give an example with real data what you want to achieve? And I wouldnt necessarily go full stream here: a stream creates ONE result, but you want TWO maps?!

– GhostCat
Feb 6 at 9:16












6 Answers
6






active

oldest

votes


















25














You can reduce each group using toMap (as a downstream collector):



Map<String, String> myMap = new HashMap<>();
myMap.put("d", "D");
myMap.put("c", "C");
myMap.put("b", "B");
myMap.put("A", "A");

List<String> myList = Arrays.asList("a", "b", "c");

Map<Boolean, Map<String, String>> result = myMap.entrySet()
.stream()
.collect(Collectors.partitioningBy(
entry -> myList.contains(entry.getKey()),
Collectors.toMap(Entry::getKey, Entry::getValue)
)
);


And for this example, that produces false=A=A, d=D, true=b=B, c=C






share|improve this answer






























    6














    Though partitioningBy is the way to go when you need both the alternatives as an output based on the condition. Yet, another way out (useful for creating map based on a single condition) is to use Collectors.filtering as :



    Map<String, String> myMap = Map.of("d", "D","c", "C","b", "B","A", "A");
    List<String> myList = List.of("a", "b", "c");
    Predicate<String> condition = myList::contains;

    Map<String, String> keysPresentInList = myMap.keySet()
    .stream()
    .collect(Collectors.filtering(condition,
    Collectors.toMap(Function.identity(), myMap::get)));
    Map<String, String> keysNotPresentInList = myMap.keySet()
    .stream()
    .collect(Collectors.filtering(Predicate.not(condition),
    Collectors.toMap(Function.identity(), myMap::get)));


    or alternatively, if you could update the existing map in-place, then you could retain entries based on their key's presence in the list using just a one-liner:



    myMap.keySet().retainAll(myList);





    share|improve this answer

























    • I guess using stream().filter( ... ).collect( ... ) would be the same ?

      – Asoub
      Feb 6 at 12:57






    • 1





      @Asoub indeed. suggested by Darshan's answer here.

      – nullpointer
      Feb 6 at 12:59


















    5














    You can't really produce two separate maps using streams (at least not in the most elegant way). Don't be afraid to use the old regular forEach, I think it's quite a clean version:



    Map<String, String> contains = new HashMap<>();
    Map<String, String> containsNot = new HashMap<>();

    for(Map.Entry<String, String> entry : yourMap.entrySet())
    if (yourList.contains(entry.getKey()))
    contains.put(entry.getKey(), entry.getValue());
    else
    containsNot.put(entry.getKey(), entry.getValue());







    share|improve this answer






























      5














      You can have filtered map by applying filtering on the original map, e.g.:



      List<String> list = new ArrayList<>(); //List of values
      Map<String, String> map = new HashMap<>();

      Map<String, String> filteredMap = map.entrySet()
      .stream()
      .filter(e -> list.contains(e.getKey()))
      .collect(Collectors.toMap(Entry::getKey, Entry::getValue));


      You can then compare the filteredMap contents with original map to extract the entries that are not present in the filteredMap.






      share|improve this answer






























        4














        You could iterate the map and use the goodies introduced in Java 8+:



        Map<Boolean, Map<String, String>> result = Map.of(true, new LinkedHashMap<>(), 
        false, new LinkedHashMap<>());
        Set<String> set = new HashSet<>(list);
        map.forEach((k, v) -> result.get(set.contains(k)).put(k, v));


        First, we create a result map with two entries, one for each partition. The values are LinkedHashMaps so that insertion order is preserved.



        Then, we create a HashSet from the list, so that invoking set.contains(k) is a O(1) operation (otherwise, if we did list.contains(k), this would be O(n) for each entry of the map, thus yielding a total time complexity of O(n^2), which is bad).



        Finally, we iterate the input map and put the (k, v) entry in the corresponding partition, as per the result of invoking set.contains(k).






        share|improve this answer
































          3














          As a supplement to @ernest_k 's answer you can use a function and groupingBy:



          Map<String, String> myMap = new HashMap<>();
          myMap.put("d", "D");
          myMap.put("c", "C");
          myMap.put("b", "B");
          myMap.put("A", "A");
          List<String> myList = Arrays.asList("a", "b", "c");

          Function<Entry<String, String> , Boolean> myCondition = i -> myList.contains(i.getKey());

          Map<Boolean,List<Entry<String, String>>> myPartedMap = myMap.entrySet()
          .stream().collect(Collectors.groupingBy(myCondition));

          System.out.println(myPartedMap);





          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%2f54549960%2fpartitioning-a-map-in-java-8%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            6 Answers
            6






            active

            oldest

            votes








            6 Answers
            6






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            25














            You can reduce each group using toMap (as a downstream collector):



            Map<String, String> myMap = new HashMap<>();
            myMap.put("d", "D");
            myMap.put("c", "C");
            myMap.put("b", "B");
            myMap.put("A", "A");

            List<String> myList = Arrays.asList("a", "b", "c");

            Map<Boolean, Map<String, String>> result = myMap.entrySet()
            .stream()
            .collect(Collectors.partitioningBy(
            entry -> myList.contains(entry.getKey()),
            Collectors.toMap(Entry::getKey, Entry::getValue)
            )
            );


            And for this example, that produces false=A=A, d=D, true=b=B, c=C






            share|improve this answer



























              25














              You can reduce each group using toMap (as a downstream collector):



              Map<String, String> myMap = new HashMap<>();
              myMap.put("d", "D");
              myMap.put("c", "C");
              myMap.put("b", "B");
              myMap.put("A", "A");

              List<String> myList = Arrays.asList("a", "b", "c");

              Map<Boolean, Map<String, String>> result = myMap.entrySet()
              .stream()
              .collect(Collectors.partitioningBy(
              entry -> myList.contains(entry.getKey()),
              Collectors.toMap(Entry::getKey, Entry::getValue)
              )
              );


              And for this example, that produces false=A=A, d=D, true=b=B, c=C






              share|improve this answer

























                25












                25








                25







                You can reduce each group using toMap (as a downstream collector):



                Map<String, String> myMap = new HashMap<>();
                myMap.put("d", "D");
                myMap.put("c", "C");
                myMap.put("b", "B");
                myMap.put("A", "A");

                List<String> myList = Arrays.asList("a", "b", "c");

                Map<Boolean, Map<String, String>> result = myMap.entrySet()
                .stream()
                .collect(Collectors.partitioningBy(
                entry -> myList.contains(entry.getKey()),
                Collectors.toMap(Entry::getKey, Entry::getValue)
                )
                );


                And for this example, that produces false=A=A, d=D, true=b=B, c=C






                share|improve this answer













                You can reduce each group using toMap (as a downstream collector):



                Map<String, String> myMap = new HashMap<>();
                myMap.put("d", "D");
                myMap.put("c", "C");
                myMap.put("b", "B");
                myMap.put("A", "A");

                List<String> myList = Arrays.asList("a", "b", "c");

                Map<Boolean, Map<String, String>> result = myMap.entrySet()
                .stream()
                .collect(Collectors.partitioningBy(
                entry -> myList.contains(entry.getKey()),
                Collectors.toMap(Entry::getKey, Entry::getValue)
                )
                );


                And for this example, that produces false=A=A, d=D, true=b=B, c=C







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Feb 6 at 9:19









                ernest_kernest_k

                23.1k42647




                23.1k42647























                    6














                    Though partitioningBy is the way to go when you need both the alternatives as an output based on the condition. Yet, another way out (useful for creating map based on a single condition) is to use Collectors.filtering as :



                    Map<String, String> myMap = Map.of("d", "D","c", "C","b", "B","A", "A");
                    List<String> myList = List.of("a", "b", "c");
                    Predicate<String> condition = myList::contains;

                    Map<String, String> keysPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(condition,
                    Collectors.toMap(Function.identity(), myMap::get)));
                    Map<String, String> keysNotPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(Predicate.not(condition),
                    Collectors.toMap(Function.identity(), myMap::get)));


                    or alternatively, if you could update the existing map in-place, then you could retain entries based on their key's presence in the list using just a one-liner:



                    myMap.keySet().retainAll(myList);





                    share|improve this answer

























                    • I guess using stream().filter( ... ).collect( ... ) would be the same ?

                      – Asoub
                      Feb 6 at 12:57






                    • 1





                      @Asoub indeed. suggested by Darshan's answer here.

                      – nullpointer
                      Feb 6 at 12:59















                    6














                    Though partitioningBy is the way to go when you need both the alternatives as an output based on the condition. Yet, another way out (useful for creating map based on a single condition) is to use Collectors.filtering as :



                    Map<String, String> myMap = Map.of("d", "D","c", "C","b", "B","A", "A");
                    List<String> myList = List.of("a", "b", "c");
                    Predicate<String> condition = myList::contains;

                    Map<String, String> keysPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(condition,
                    Collectors.toMap(Function.identity(), myMap::get)));
                    Map<String, String> keysNotPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(Predicate.not(condition),
                    Collectors.toMap(Function.identity(), myMap::get)));


                    or alternatively, if you could update the existing map in-place, then you could retain entries based on their key's presence in the list using just a one-liner:



                    myMap.keySet().retainAll(myList);





                    share|improve this answer

























                    • I guess using stream().filter( ... ).collect( ... ) would be the same ?

                      – Asoub
                      Feb 6 at 12:57






                    • 1





                      @Asoub indeed. suggested by Darshan's answer here.

                      – nullpointer
                      Feb 6 at 12:59













                    6












                    6








                    6







                    Though partitioningBy is the way to go when you need both the alternatives as an output based on the condition. Yet, another way out (useful for creating map based on a single condition) is to use Collectors.filtering as :



                    Map<String, String> myMap = Map.of("d", "D","c", "C","b", "B","A", "A");
                    List<String> myList = List.of("a", "b", "c");
                    Predicate<String> condition = myList::contains;

                    Map<String, String> keysPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(condition,
                    Collectors.toMap(Function.identity(), myMap::get)));
                    Map<String, String> keysNotPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(Predicate.not(condition),
                    Collectors.toMap(Function.identity(), myMap::get)));


                    or alternatively, if you could update the existing map in-place, then you could retain entries based on their key's presence in the list using just a one-liner:



                    myMap.keySet().retainAll(myList);





                    share|improve this answer















                    Though partitioningBy is the way to go when you need both the alternatives as an output based on the condition. Yet, another way out (useful for creating map based on a single condition) is to use Collectors.filtering as :



                    Map<String, String> myMap = Map.of("d", "D","c", "C","b", "B","A", "A");
                    List<String> myList = List.of("a", "b", "c");
                    Predicate<String> condition = myList::contains;

                    Map<String, String> keysPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(condition,
                    Collectors.toMap(Function.identity(), myMap::get)));
                    Map<String, String> keysNotPresentInList = myMap.keySet()
                    .stream()
                    .collect(Collectors.filtering(Predicate.not(condition),
                    Collectors.toMap(Function.identity(), myMap::get)));


                    or alternatively, if you could update the existing map in-place, then you could retain entries based on their key's presence in the list using just a one-liner:



                    myMap.keySet().retainAll(myList);






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Feb 6 at 11:31

























                    answered Feb 6 at 11:14









                    nullpointernullpointer

                    43.3k10101200




                    43.3k10101200












                    • I guess using stream().filter( ... ).collect( ... ) would be the same ?

                      – Asoub
                      Feb 6 at 12:57






                    • 1





                      @Asoub indeed. suggested by Darshan's answer here.

                      – nullpointer
                      Feb 6 at 12:59

















                    • I guess using stream().filter( ... ).collect( ... ) would be the same ?

                      – Asoub
                      Feb 6 at 12:57






                    • 1





                      @Asoub indeed. suggested by Darshan's answer here.

                      – nullpointer
                      Feb 6 at 12:59
















                    I guess using stream().filter( ... ).collect( ... ) would be the same ?

                    – Asoub
                    Feb 6 at 12:57





                    I guess using stream().filter( ... ).collect( ... ) would be the same ?

                    – Asoub
                    Feb 6 at 12:57




                    1




                    1





                    @Asoub indeed. suggested by Darshan's answer here.

                    – nullpointer
                    Feb 6 at 12:59





                    @Asoub indeed. suggested by Darshan's answer here.

                    – nullpointer
                    Feb 6 at 12:59











                    5














                    You can't really produce two separate maps using streams (at least not in the most elegant way). Don't be afraid to use the old regular forEach, I think it's quite a clean version:



                    Map<String, String> contains = new HashMap<>();
                    Map<String, String> containsNot = new HashMap<>();

                    for(Map.Entry<String, String> entry : yourMap.entrySet())
                    if (yourList.contains(entry.getKey()))
                    contains.put(entry.getKey(), entry.getValue());
                    else
                    containsNot.put(entry.getKey(), entry.getValue());







                    share|improve this answer



























                      5














                      You can't really produce two separate maps using streams (at least not in the most elegant way). Don't be afraid to use the old regular forEach, I think it's quite a clean version:



                      Map<String, String> contains = new HashMap<>();
                      Map<String, String> containsNot = new HashMap<>();

                      for(Map.Entry<String, String> entry : yourMap.entrySet())
                      if (yourList.contains(entry.getKey()))
                      contains.put(entry.getKey(), entry.getValue());
                      else
                      containsNot.put(entry.getKey(), entry.getValue());







                      share|improve this answer

























                        5












                        5








                        5







                        You can't really produce two separate maps using streams (at least not in the most elegant way). Don't be afraid to use the old regular forEach, I think it's quite a clean version:



                        Map<String, String> contains = new HashMap<>();
                        Map<String, String> containsNot = new HashMap<>();

                        for(Map.Entry<String, String> entry : yourMap.entrySet())
                        if (yourList.contains(entry.getKey()))
                        contains.put(entry.getKey(), entry.getValue());
                        else
                        containsNot.put(entry.getKey(), entry.getValue());







                        share|improve this answer













                        You can't really produce two separate maps using streams (at least not in the most elegant way). Don't be afraid to use the old regular forEach, I think it's quite a clean version:



                        Map<String, String> contains = new HashMap<>();
                        Map<String, String> containsNot = new HashMap<>();

                        for(Map.Entry<String, String> entry : yourMap.entrySet())
                        if (yourList.contains(entry.getKey()))
                        contains.put(entry.getKey(), entry.getValue());
                        else
                        containsNot.put(entry.getKey(), entry.getValue());








                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Feb 6 at 9:17









                        Schidu LucaSchidu Luca

                        3,042521




                        3,042521





















                            5














                            You can have filtered map by applying filtering on the original map, e.g.:



                            List<String> list = new ArrayList<>(); //List of values
                            Map<String, String> map = new HashMap<>();

                            Map<String, String> filteredMap = map.entrySet()
                            .stream()
                            .filter(e -> list.contains(e.getKey()))
                            .collect(Collectors.toMap(Entry::getKey, Entry::getValue));


                            You can then compare the filteredMap contents with original map to extract the entries that are not present in the filteredMap.






                            share|improve this answer



























                              5














                              You can have filtered map by applying filtering on the original map, e.g.:



                              List<String> list = new ArrayList<>(); //List of values
                              Map<String, String> map = new HashMap<>();

                              Map<String, String> filteredMap = map.entrySet()
                              .stream()
                              .filter(e -> list.contains(e.getKey()))
                              .collect(Collectors.toMap(Entry::getKey, Entry::getValue));


                              You can then compare the filteredMap contents with original map to extract the entries that are not present in the filteredMap.






                              share|improve this answer

























                                5












                                5








                                5







                                You can have filtered map by applying filtering on the original map, e.g.:



                                List<String> list = new ArrayList<>(); //List of values
                                Map<String, String> map = new HashMap<>();

                                Map<String, String> filteredMap = map.entrySet()
                                .stream()
                                .filter(e -> list.contains(e.getKey()))
                                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));


                                You can then compare the filteredMap contents with original map to extract the entries that are not present in the filteredMap.






                                share|improve this answer













                                You can have filtered map by applying filtering on the original map, e.g.:



                                List<String> list = new ArrayList<>(); //List of values
                                Map<String, String> map = new HashMap<>();

                                Map<String, String> filteredMap = map.entrySet()
                                .stream()
                                .filter(e -> list.contains(e.getKey()))
                                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));


                                You can then compare the filteredMap contents with original map to extract the entries that are not present in the filteredMap.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Feb 6 at 9:19









                                Darshan MehtaDarshan Mehta

                                22.9k32953




                                22.9k32953





















                                    4














                                    You could iterate the map and use the goodies introduced in Java 8+:



                                    Map<Boolean, Map<String, String>> result = Map.of(true, new LinkedHashMap<>(), 
                                    false, new LinkedHashMap<>());
                                    Set<String> set = new HashSet<>(list);
                                    map.forEach((k, v) -> result.get(set.contains(k)).put(k, v));


                                    First, we create a result map with two entries, one for each partition. The values are LinkedHashMaps so that insertion order is preserved.



                                    Then, we create a HashSet from the list, so that invoking set.contains(k) is a O(1) operation (otherwise, if we did list.contains(k), this would be O(n) for each entry of the map, thus yielding a total time complexity of O(n^2), which is bad).



                                    Finally, we iterate the input map and put the (k, v) entry in the corresponding partition, as per the result of invoking set.contains(k).






                                    share|improve this answer





























                                      4














                                      You could iterate the map and use the goodies introduced in Java 8+:



                                      Map<Boolean, Map<String, String>> result = Map.of(true, new LinkedHashMap<>(), 
                                      false, new LinkedHashMap<>());
                                      Set<String> set = new HashSet<>(list);
                                      map.forEach((k, v) -> result.get(set.contains(k)).put(k, v));


                                      First, we create a result map with two entries, one for each partition. The values are LinkedHashMaps so that insertion order is preserved.



                                      Then, we create a HashSet from the list, so that invoking set.contains(k) is a O(1) operation (otherwise, if we did list.contains(k), this would be O(n) for each entry of the map, thus yielding a total time complexity of O(n^2), which is bad).



                                      Finally, we iterate the input map and put the (k, v) entry in the corresponding partition, as per the result of invoking set.contains(k).






                                      share|improve this answer



























                                        4












                                        4








                                        4







                                        You could iterate the map and use the goodies introduced in Java 8+:



                                        Map<Boolean, Map<String, String>> result = Map.of(true, new LinkedHashMap<>(), 
                                        false, new LinkedHashMap<>());
                                        Set<String> set = new HashSet<>(list);
                                        map.forEach((k, v) -> result.get(set.contains(k)).put(k, v));


                                        First, we create a result map with two entries, one for each partition. The values are LinkedHashMaps so that insertion order is preserved.



                                        Then, we create a HashSet from the list, so that invoking set.contains(k) is a O(1) operation (otherwise, if we did list.contains(k), this would be O(n) for each entry of the map, thus yielding a total time complexity of O(n^2), which is bad).



                                        Finally, we iterate the input map and put the (k, v) entry in the corresponding partition, as per the result of invoking set.contains(k).






                                        share|improve this answer















                                        You could iterate the map and use the goodies introduced in Java 8+:



                                        Map<Boolean, Map<String, String>> result = Map.of(true, new LinkedHashMap<>(), 
                                        false, new LinkedHashMap<>());
                                        Set<String> set = new HashSet<>(list);
                                        map.forEach((k, v) -> result.get(set.contains(k)).put(k, v));


                                        First, we create a result map with two entries, one for each partition. The values are LinkedHashMaps so that insertion order is preserved.



                                        Then, we create a HashSet from the list, so that invoking set.contains(k) is a O(1) operation (otherwise, if we did list.contains(k), this would be O(n) for each entry of the map, thus yielding a total time complexity of O(n^2), which is bad).



                                        Finally, we iterate the input map and put the (k, v) entry in the corresponding partition, as per the result of invoking set.contains(k).







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Feb 6 at 13:08

























                                        answered Feb 6 at 12:32









                                        Federico Peralta SchaffnerFederico Peralta Schaffner

                                        23.4k43677




                                        23.4k43677





















                                            3














                                            As a supplement to @ernest_k 's answer you can use a function and groupingBy:



                                            Map<String, String> myMap = new HashMap<>();
                                            myMap.put("d", "D");
                                            myMap.put("c", "C");
                                            myMap.put("b", "B");
                                            myMap.put("A", "A");
                                            List<String> myList = Arrays.asList("a", "b", "c");

                                            Function<Entry<String, String> , Boolean> myCondition = i -> myList.contains(i.getKey());

                                            Map<Boolean,List<Entry<String, String>>> myPartedMap = myMap.entrySet()
                                            .stream().collect(Collectors.groupingBy(myCondition));

                                            System.out.println(myPartedMap);





                                            share|improve this answer





























                                              3














                                              As a supplement to @ernest_k 's answer you can use a function and groupingBy:



                                              Map<String, String> myMap = new HashMap<>();
                                              myMap.put("d", "D");
                                              myMap.put("c", "C");
                                              myMap.put("b", "B");
                                              myMap.put("A", "A");
                                              List<String> myList = Arrays.asList("a", "b", "c");

                                              Function<Entry<String, String> , Boolean> myCondition = i -> myList.contains(i.getKey());

                                              Map<Boolean,List<Entry<String, String>>> myPartedMap = myMap.entrySet()
                                              .stream().collect(Collectors.groupingBy(myCondition));

                                              System.out.println(myPartedMap);





                                              share|improve this answer



























                                                3












                                                3








                                                3







                                                As a supplement to @ernest_k 's answer you can use a function and groupingBy:



                                                Map<String, String> myMap = new HashMap<>();
                                                myMap.put("d", "D");
                                                myMap.put("c", "C");
                                                myMap.put("b", "B");
                                                myMap.put("A", "A");
                                                List<String> myList = Arrays.asList("a", "b", "c");

                                                Function<Entry<String, String> , Boolean> myCondition = i -> myList.contains(i.getKey());

                                                Map<Boolean,List<Entry<String, String>>> myPartedMap = myMap.entrySet()
                                                .stream().collect(Collectors.groupingBy(myCondition));

                                                System.out.println(myPartedMap);





                                                share|improve this answer















                                                As a supplement to @ernest_k 's answer you can use a function and groupingBy:



                                                Map<String, String> myMap = new HashMap<>();
                                                myMap.put("d", "D");
                                                myMap.put("c", "C");
                                                myMap.put("b", "B");
                                                myMap.put("A", "A");
                                                List<String> myList = Arrays.asList("a", "b", "c");

                                                Function<Entry<String, String> , Boolean> myCondition = i -> myList.contains(i.getKey());

                                                Map<Boolean,List<Entry<String, String>>> myPartedMap = myMap.entrySet()
                                                .stream().collect(Collectors.groupingBy(myCondition));

                                                System.out.println(myPartedMap);






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Feb 7 at 6:09









                                                Gaurang Tandon

                                                3,86862457




                                                3,86862457










                                                answered Feb 6 at 9:46









                                                EritreanEritrean

                                                3,6181914




                                                3,6181914



























                                                    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%2f54549960%2fpartitioning-a-map-in-java-8%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

                                                    How to check contact read email or not when send email to Individual?

                                                    Bahrain

                                                    Postfix configuration issue with fips on centos 7; mailgun relay