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

                              Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                              ComboBox Display Member on multiple fields

                              Is it possible to collect Nectar points via Trainline?