Java Streams: Issue about collect to a Map











up vote
12
down vote

favorite
1












I'm running against an issue:



I've created this stream I need to map to a Map<String, Object>:



private Map<String, Object> collectArguments(JoinPoint point) {
CodeSignature signature = (CodeSignature) point.getSignature();
String argNames = signature.getParameterNames();
Object args = point.getArgs();

return IntStream.range(0, args.length)
.collect(Collectors.toMap(param -> argNames[param], param -> args[param]));
}


I'm getting the following message, which I don't quite figure out:



[Java] Type mismatch: cannot convert from Collector<Object,capture#3-of ?,Map<Object,Object>> to Supplier<R>









share|improve this question




























    up vote
    12
    down vote

    favorite
    1












    I'm running against an issue:



    I've created this stream I need to map to a Map<String, Object>:



    private Map<String, Object> collectArguments(JoinPoint point) {
    CodeSignature signature = (CodeSignature) point.getSignature();
    String argNames = signature.getParameterNames();
    Object args = point.getArgs();

    return IntStream.range(0, args.length)
    .collect(Collectors.toMap(param -> argNames[param], param -> args[param]));
    }


    I'm getting the following message, which I don't quite figure out:



    [Java] Type mismatch: cannot convert from Collector<Object,capture#3-of ?,Map<Object,Object>> to Supplier<R>









    share|improve this question


























      up vote
      12
      down vote

      favorite
      1









      up vote
      12
      down vote

      favorite
      1






      1





      I'm running against an issue:



      I've created this stream I need to map to a Map<String, Object>:



      private Map<String, Object> collectArguments(JoinPoint point) {
      CodeSignature signature = (CodeSignature) point.getSignature();
      String argNames = signature.getParameterNames();
      Object args = point.getArgs();

      return IntStream.range(0, args.length)
      .collect(Collectors.toMap(param -> argNames[param], param -> args[param]));
      }


      I'm getting the following message, which I don't quite figure out:



      [Java] Type mismatch: cannot convert from Collector<Object,capture#3-of ?,Map<Object,Object>> to Supplier<R>









      share|improve this question















      I'm running against an issue:



      I've created this stream I need to map to a Map<String, Object>:



      private Map<String, Object> collectArguments(JoinPoint point) {
      CodeSignature signature = (CodeSignature) point.getSignature();
      String argNames = signature.getParameterNames();
      Object args = point.getArgs();

      return IntStream.range(0, args.length)
      .collect(Collectors.toMap(param -> argNames[param], param -> args[param]));
      }


      I'm getting the following message, which I don't quite figure out:



      [Java] Type mismatch: cannot convert from Collector<Object,capture#3-of ?,Map<Object,Object>> to Supplier<R>






      java java-8 java-stream






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday









      Eran

      271k35428510




      271k35428510










      asked yesterday









      Jordi

      3,71183174




      3,71183174
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          17
          down vote



          accepted










          IntStream doesn't have a collect method that accepts a Collector. It only has a 3 argument collect method having this signature:



          <R> R collect(Supplier<R> supplier,
          ObjIntConsumer<R> accumulator,
          BiConsumer<R, R> combiner)


          Perhaps you should use a Stream<Integer>:



          return IntStream.range(0, args.length)
          .boxed()
          .collect(Collectors.toMap(param -> argNames[param],
          param -> args[param]));


          Or, if you wish to use the collect method of IntStream, it would look like this:



          return IntStream.range(0, args.length)
          .collect(HashMap::new,
          (m,i)->m.put(argNames[i],args[i]),
          (m1,m2)->m1.putAll (m2));


          or



          return IntStream.range(0, args.length)
          .collect(HashMap::new,
          (m,i)->m.put(argNames[i],args[i]),
          Map::putAll);





          share|improve this answer






























            up vote
            2
            down vote













            An alternative to Eran's answer (in which the first variant, to use a Stream<Integer> is really neat) would be to first map the content of the arrays to an object:



            public class Argument {
            private final String argName;
            private final Object arg;

            public Argument(String argName, Object arg) {
            this.argName = argName;
            this.arg = arg;
            }

            public String getArgName() {
            return argName;
            }

            public Object getArg() {
            return arg;
            }
            }


            The code for collecting this object to a map becomes a very clear and concise basic stream:



            Map<String, Object> map = IntStream.range(0, args.length)
            .mapToObj(i -> new Argument(argNames[i], args[i]))
            .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));


            Perhaps even extract the logic for creating Arguments into its own method:



            private List<Argument> toArguments(JoinPoint point) {
            String argNames = ((CodeSignature) point.getSignature()).getParameterNames();
            return IntStream.range(0, point.getArgs().length)
            .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
            .collect(Collectors.toList());
            }


            Doing this, your collectArguments() method would be a simple one-liner:



            private Map<String, Object> collectArguments(JoinPoint point) {
            return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
            }





            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%2f53261934%2fjava-streams-issue-about-collect-to-a-mapstring-object%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
              17
              down vote



              accepted










              IntStream doesn't have a collect method that accepts a Collector. It only has a 3 argument collect method having this signature:



              <R> R collect(Supplier<R> supplier,
              ObjIntConsumer<R> accumulator,
              BiConsumer<R, R> combiner)


              Perhaps you should use a Stream<Integer>:



              return IntStream.range(0, args.length)
              .boxed()
              .collect(Collectors.toMap(param -> argNames[param],
              param -> args[param]));


              Or, if you wish to use the collect method of IntStream, it would look like this:



              return IntStream.range(0, args.length)
              .collect(HashMap::new,
              (m,i)->m.put(argNames[i],args[i]),
              (m1,m2)->m1.putAll (m2));


              or



              return IntStream.range(0, args.length)
              .collect(HashMap::new,
              (m,i)->m.put(argNames[i],args[i]),
              Map::putAll);





              share|improve this answer



























                up vote
                17
                down vote



                accepted










                IntStream doesn't have a collect method that accepts a Collector. It only has a 3 argument collect method having this signature:



                <R> R collect(Supplier<R> supplier,
                ObjIntConsumer<R> accumulator,
                BiConsumer<R, R> combiner)


                Perhaps you should use a Stream<Integer>:



                return IntStream.range(0, args.length)
                .boxed()
                .collect(Collectors.toMap(param -> argNames[param],
                param -> args[param]));


                Or, if you wish to use the collect method of IntStream, it would look like this:



                return IntStream.range(0, args.length)
                .collect(HashMap::new,
                (m,i)->m.put(argNames[i],args[i]),
                (m1,m2)->m1.putAll (m2));


                or



                return IntStream.range(0, args.length)
                .collect(HashMap::new,
                (m,i)->m.put(argNames[i],args[i]),
                Map::putAll);





                share|improve this answer

























                  up vote
                  17
                  down vote



                  accepted







                  up vote
                  17
                  down vote



                  accepted






                  IntStream doesn't have a collect method that accepts a Collector. It only has a 3 argument collect method having this signature:



                  <R> R collect(Supplier<R> supplier,
                  ObjIntConsumer<R> accumulator,
                  BiConsumer<R, R> combiner)


                  Perhaps you should use a Stream<Integer>:



                  return IntStream.range(0, args.length)
                  .boxed()
                  .collect(Collectors.toMap(param -> argNames[param],
                  param -> args[param]));


                  Or, if you wish to use the collect method of IntStream, it would look like this:



                  return IntStream.range(0, args.length)
                  .collect(HashMap::new,
                  (m,i)->m.put(argNames[i],args[i]),
                  (m1,m2)->m1.putAll (m2));


                  or



                  return IntStream.range(0, args.length)
                  .collect(HashMap::new,
                  (m,i)->m.put(argNames[i],args[i]),
                  Map::putAll);





                  share|improve this answer














                  IntStream doesn't have a collect method that accepts a Collector. It only has a 3 argument collect method having this signature:



                  <R> R collect(Supplier<R> supplier,
                  ObjIntConsumer<R> accumulator,
                  BiConsumer<R, R> combiner)


                  Perhaps you should use a Stream<Integer>:



                  return IntStream.range(0, args.length)
                  .boxed()
                  .collect(Collectors.toMap(param -> argNames[param],
                  param -> args[param]));


                  Or, if you wish to use the collect method of IntStream, it would look like this:



                  return IntStream.range(0, args.length)
                  .collect(HashMap::new,
                  (m,i)->m.put(argNames[i],args[i]),
                  (m1,m2)->m1.putAll (m2));


                  or



                  return IntStream.range(0, args.length)
                  .collect(HashMap::new,
                  (m,i)->m.put(argNames[i],args[i]),
                  Map::putAll);






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited yesterday

























                  answered yesterday









                  Eran

                  271k35428510




                  271k35428510
























                      up vote
                      2
                      down vote













                      An alternative to Eran's answer (in which the first variant, to use a Stream<Integer> is really neat) would be to first map the content of the arrays to an object:



                      public class Argument {
                      private final String argName;
                      private final Object arg;

                      public Argument(String argName, Object arg) {
                      this.argName = argName;
                      this.arg = arg;
                      }

                      public String getArgName() {
                      return argName;
                      }

                      public Object getArg() {
                      return arg;
                      }
                      }


                      The code for collecting this object to a map becomes a very clear and concise basic stream:



                      Map<String, Object> map = IntStream.range(0, args.length)
                      .mapToObj(i -> new Argument(argNames[i], args[i]))
                      .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));


                      Perhaps even extract the logic for creating Arguments into its own method:



                      private List<Argument> toArguments(JoinPoint point) {
                      String argNames = ((CodeSignature) point.getSignature()).getParameterNames();
                      return IntStream.range(0, point.getArgs().length)
                      .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
                      .collect(Collectors.toList());
                      }


                      Doing this, your collectArguments() method would be a simple one-liner:



                      private Map<String, Object> collectArguments(JoinPoint point) {
                      return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
                      }





                      share|improve this answer

























                        up vote
                        2
                        down vote













                        An alternative to Eran's answer (in which the first variant, to use a Stream<Integer> is really neat) would be to first map the content of the arrays to an object:



                        public class Argument {
                        private final String argName;
                        private final Object arg;

                        public Argument(String argName, Object arg) {
                        this.argName = argName;
                        this.arg = arg;
                        }

                        public String getArgName() {
                        return argName;
                        }

                        public Object getArg() {
                        return arg;
                        }
                        }


                        The code for collecting this object to a map becomes a very clear and concise basic stream:



                        Map<String, Object> map = IntStream.range(0, args.length)
                        .mapToObj(i -> new Argument(argNames[i], args[i]))
                        .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));


                        Perhaps even extract the logic for creating Arguments into its own method:



                        private List<Argument> toArguments(JoinPoint point) {
                        String argNames = ((CodeSignature) point.getSignature()).getParameterNames();
                        return IntStream.range(0, point.getArgs().length)
                        .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
                        .collect(Collectors.toList());
                        }


                        Doing this, your collectArguments() method would be a simple one-liner:



                        private Map<String, Object> collectArguments(JoinPoint point) {
                        return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
                        }





                        share|improve this answer























                          up vote
                          2
                          down vote










                          up vote
                          2
                          down vote









                          An alternative to Eran's answer (in which the first variant, to use a Stream<Integer> is really neat) would be to first map the content of the arrays to an object:



                          public class Argument {
                          private final String argName;
                          private final Object arg;

                          public Argument(String argName, Object arg) {
                          this.argName = argName;
                          this.arg = arg;
                          }

                          public String getArgName() {
                          return argName;
                          }

                          public Object getArg() {
                          return arg;
                          }
                          }


                          The code for collecting this object to a map becomes a very clear and concise basic stream:



                          Map<String, Object> map = IntStream.range(0, args.length)
                          .mapToObj(i -> new Argument(argNames[i], args[i]))
                          .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));


                          Perhaps even extract the logic for creating Arguments into its own method:



                          private List<Argument> toArguments(JoinPoint point) {
                          String argNames = ((CodeSignature) point.getSignature()).getParameterNames();
                          return IntStream.range(0, point.getArgs().length)
                          .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
                          .collect(Collectors.toList());
                          }


                          Doing this, your collectArguments() method would be a simple one-liner:



                          private Map<String, Object> collectArguments(JoinPoint point) {
                          return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
                          }





                          share|improve this answer












                          An alternative to Eran's answer (in which the first variant, to use a Stream<Integer> is really neat) would be to first map the content of the arrays to an object:



                          public class Argument {
                          private final String argName;
                          private final Object arg;

                          public Argument(String argName, Object arg) {
                          this.argName = argName;
                          this.arg = arg;
                          }

                          public String getArgName() {
                          return argName;
                          }

                          public Object getArg() {
                          return arg;
                          }
                          }


                          The code for collecting this object to a map becomes a very clear and concise basic stream:



                          Map<String, Object> map = IntStream.range(0, args.length)
                          .mapToObj(i -> new Argument(argNames[i], args[i]))
                          .collect(Collectors.toMap(Argument::getArgName, Argument::getArg));


                          Perhaps even extract the logic for creating Arguments into its own method:



                          private List<Argument> toArguments(JoinPoint point) {
                          String argNames = ((CodeSignature) point.getSignature()).getParameterNames();
                          return IntStream.range(0, point.getArgs().length)
                          .mapToObj(i -> new Argument(argNames[i], point.getArgs()[i]))
                          .collect(Collectors.toList());
                          }


                          Doing this, your collectArguments() method would be a simple one-liner:



                          private Map<String, Object> collectArguments(JoinPoint point) {
                          return toArguments(point).stream().collect(toMap(Argument::getArgName, Argument::getArg));
                          }






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered yesterday









                          Magnilex

                          6,84363459




                          6,84363459






























                               

                              draft saved


                              draft discarded



















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261934%2fjava-streams-issue-about-collect-to-a-mapstring-object%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest




















































































                              Popular posts from this blog

                              How to change which sound is reproduced for terminal bell?

                              Can I use Tabulator js library in my java Spring + Thymeleaf project?

                              Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents