Merging, sorting and limit Map streams using Java 8

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





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I have two maps map1 and map2 . I want to merge both maps and then sort in desc order and get top 5. In case of duplicate keys in merge I need to sum the values. I have the following code that works:



Map<String, Long> topFive = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)))
.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(5).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(v1,v2) -> v1,
LinkedHashMap::new));


But I would like to know if there is a better solution.







share|improve this question

























    up vote
    1
    down vote

    favorite












    I have two maps map1 and map2 . I want to merge both maps and then sort in desc order and get top 5. In case of duplicate keys in merge I need to sum the values. I have the following code that works:



    Map<String, Long> topFive = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)))
    .entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
    .limit(5).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
    (v1,v2) -> v1,
    LinkedHashMap::new));


    But I would like to know if there is a better solution.







    share|improve this question





















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have two maps map1 and map2 . I want to merge both maps and then sort in desc order and get top 5. In case of duplicate keys in merge I need to sum the values. I have the following code that works:



      Map<String, Long> topFive = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)))
      .entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
      .limit(5).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
      (v1,v2) -> v1,
      LinkedHashMap::new));


      But I would like to know if there is a better solution.







      share|improve this question











      I have two maps map1 and map2 . I want to merge both maps and then sort in desc order and get top 5. In case of duplicate keys in merge I need to sum the values. I have the following code that works:



      Map<String, Long> topFive = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)))
      .entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
      .limit(5).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
      (v1,v2) -> v1,
      LinkedHashMap::new));


      But I would like to know if there is a better solution.









      share|improve this question










      share|improve this question




      share|improve this question









      asked Mar 22 at 5:20









      nufar

      61




      61




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote













          The question for a "better" solution is bound to be quite opinion-based. As far as the actual code goes, I think you are quite close to the optimum. As for readability... well, Roland already shared his initial thoughts and I totally agree. This is bound to be a nightmare for the poor maintenance programmer.



          Thus: a suggestion which is nothing new, but just a little rearangement:



          private Map<String, Long> getHistogramTopFive(Map<String, Long> map1, Map<String, Long> map2) 
          Map<String, Long> mergedMap = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)));

          Map<String, Long> topFive = mergedMap.entrySet().stream()
          .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
          .limit(5)
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
          (v1,v2) -> v1,
          LinkedHashMap::new));

          return topFive;



          By putting it into a method and naming this method, you document your business intention. Furthermore, by breaking up the long command chain with a new mergedMap variable in between, the code gains much in readability.



          The additional line-breaks in the second part are what I consider best practices in streaming API: each new operation on a new line.






          share|improve this answer




























            up vote
            0
            down vote













            When I first saw the code it looked frightening because it is a solid rectangle of characters, with no apparent structure. It looks like you wrote a novel in a single paragraph.



            Then I took a deep breath and slowly read the code from the beginning to the end, which made me think: yes, it's exactly what you deccibed in natural language above. It's sad that the code is so much longer than your description.



            Basically you are dealing with a histogram, which is a Map<T, Long> sorted by the values. Therefore, try to find a third-party library that offers a histogram class, and then your code may read:



            var topFive = Histogram.create(map1).addAll(map2).top(5);


            I don't know of such a library from the top of my head, but it surely exists.






            share|improve this answer





















              Your Answer




              StackExchange.ifUsing("editor", function ()
              return StackExchange.using("mathjaxEditing", function ()
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              );
              );
              , "mathjax-editing");

              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: "196"
              ;
              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: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190168%2fmerging-sorting-and-limit-map-streams-using-java-8%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              The question for a "better" solution is bound to be quite opinion-based. As far as the actual code goes, I think you are quite close to the optimum. As for readability... well, Roland already shared his initial thoughts and I totally agree. This is bound to be a nightmare for the poor maintenance programmer.



              Thus: a suggestion which is nothing new, but just a little rearangement:



              private Map<String, Long> getHistogramTopFive(Map<String, Long> map1, Map<String, Long> map2) 
              Map<String, Long> mergedMap = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)));

              Map<String, Long> topFive = mergedMap.entrySet().stream()
              .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
              .limit(5)
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
              (v1,v2) -> v1,
              LinkedHashMap::new));

              return topFive;



              By putting it into a method and naming this method, you document your business intention. Furthermore, by breaking up the long command chain with a new mergedMap variable in between, the code gains much in readability.



              The additional line-breaks in the second part are what I consider best practices in streaming API: each new operation on a new line.






              share|improve this answer

























                up vote
                1
                down vote













                The question for a "better" solution is bound to be quite opinion-based. As far as the actual code goes, I think you are quite close to the optimum. As for readability... well, Roland already shared his initial thoughts and I totally agree. This is bound to be a nightmare for the poor maintenance programmer.



                Thus: a suggestion which is nothing new, but just a little rearangement:



                private Map<String, Long> getHistogramTopFive(Map<String, Long> map1, Map<String, Long> map2) 
                Map<String, Long> mergedMap = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)));

                Map<String, Long> topFive = mergedMap.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(5)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (v1,v2) -> v1,
                LinkedHashMap::new));

                return topFive;



                By putting it into a method and naming this method, you document your business intention. Furthermore, by breaking up the long command chain with a new mergedMap variable in between, the code gains much in readability.



                The additional line-breaks in the second part are what I consider best practices in streaming API: each new operation on a new line.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  The question for a "better" solution is bound to be quite opinion-based. As far as the actual code goes, I think you are quite close to the optimum. As for readability... well, Roland already shared his initial thoughts and I totally agree. This is bound to be a nightmare for the poor maintenance programmer.



                  Thus: a suggestion which is nothing new, but just a little rearangement:



                  private Map<String, Long> getHistogramTopFive(Map<String, Long> map1, Map<String, Long> map2) 
                  Map<String, Long> mergedMap = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)));

                  Map<String, Long> topFive = mergedMap.entrySet().stream()
                  .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                  .limit(5)
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                  (v1,v2) -> v1,
                  LinkedHashMap::new));

                  return topFive;



                  By putting it into a method and naming this method, you document your business intention. Furthermore, by breaking up the long command chain with a new mergedMap variable in between, the code gains much in readability.



                  The additional line-breaks in the second part are what I consider best practices in streaming API: each new operation on a new line.






                  share|improve this answer













                  The question for a "better" solution is bound to be quite opinion-based. As far as the actual code goes, I think you are quite close to the optimum. As for readability... well, Roland already shared his initial thoughts and I totally agree. This is bound to be a nightmare for the poor maintenance programmer.



                  Thus: a suggestion which is nothing new, but just a little rearangement:



                  private Map<String, Long> getHistogramTopFive(Map<String, Long> map1, Map<String, Long> map2) 
                  Map<String, Long> mergedMap = (Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)));

                  Map<String, Long> topFive = mergedMap.entrySet().stream()
                  .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                  .limit(5)
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                  (v1,v2) -> v1,
                  LinkedHashMap::new));

                  return topFive;



                  By putting it into a method and naming this method, you document your business intention. Furthermore, by breaking up the long command chain with a new mergedMap variable in between, the code gains much in readability.



                  The additional line-breaks in the second part are what I consider best practices in streaming API: each new operation on a new line.







                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Mar 22 at 6:40









                  mtj

                  2,675212




                  2,675212






















                      up vote
                      0
                      down vote













                      When I first saw the code it looked frightening because it is a solid rectangle of characters, with no apparent structure. It looks like you wrote a novel in a single paragraph.



                      Then I took a deep breath and slowly read the code from the beginning to the end, which made me think: yes, it's exactly what you deccibed in natural language above. It's sad that the code is so much longer than your description.



                      Basically you are dealing with a histogram, which is a Map<T, Long> sorted by the values. Therefore, try to find a third-party library that offers a histogram class, and then your code may read:



                      var topFive = Histogram.create(map1).addAll(map2).top(5);


                      I don't know of such a library from the top of my head, but it surely exists.






                      share|improve this answer

























                        up vote
                        0
                        down vote













                        When I first saw the code it looked frightening because it is a solid rectangle of characters, with no apparent structure. It looks like you wrote a novel in a single paragraph.



                        Then I took a deep breath and slowly read the code from the beginning to the end, which made me think: yes, it's exactly what you deccibed in natural language above. It's sad that the code is so much longer than your description.



                        Basically you are dealing with a histogram, which is a Map<T, Long> sorted by the values. Therefore, try to find a third-party library that offers a histogram class, and then your code may read:



                        var topFive = Histogram.create(map1).addAll(map2).top(5);


                        I don't know of such a library from the top of my head, but it surely exists.






                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          When I first saw the code it looked frightening because it is a solid rectangle of characters, with no apparent structure. It looks like you wrote a novel in a single paragraph.



                          Then I took a deep breath and slowly read the code from the beginning to the end, which made me think: yes, it's exactly what you deccibed in natural language above. It's sad that the code is so much longer than your description.



                          Basically you are dealing with a histogram, which is a Map<T, Long> sorted by the values. Therefore, try to find a third-party library that offers a histogram class, and then your code may read:



                          var topFive = Histogram.create(map1).addAll(map2).top(5);


                          I don't know of such a library from the top of my head, but it surely exists.






                          share|improve this answer













                          When I first saw the code it looked frightening because it is a solid rectangle of characters, with no apparent structure. It looks like you wrote a novel in a single paragraph.



                          Then I took a deep breath and slowly read the code from the beginning to the end, which made me think: yes, it's exactly what you deccibed in natural language above. It's sad that the code is so much longer than your description.



                          Basically you are dealing with a histogram, which is a Map<T, Long> sorted by the values. Therefore, try to find a third-party library that offers a histogram class, and then your code may read:



                          var topFive = Histogram.create(map1).addAll(map2).top(5);


                          I don't know of such a library from the top of my head, but it surely exists.







                          share|improve this answer













                          share|improve this answer



                          share|improve this answer











                          answered Mar 22 at 5:38









                          Roland Illig

                          10.4k11543




                          10.4k11543






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190168%2fmerging-sorting-and-limit-map-streams-using-java-8%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Greedy Best First Search implementation in Rust

                              Function to Return a JSON Like Objects Using VBA Collections and Arrays

                              C++11 CLH Lock Implementation