Stream.findFirst different than Optional.of?Differences between HashMap and Hashtable?What is the difference...

Exploding Numbers

What does “to the numbers” mean in landing clearance?

Can I use a larger HVAC Hard Start kit than is recommended?

How do I handle a blinded enemy which wants to attack someone it's sure is there?

Can I legally make a website about boycotting a certain company?

Can "ee" appear in Latin?

How can a kingdom keep the secret of a missing monarch from the public?

How to encircle section of matrix in LaTeX?

What caused Doctor Strange to repent of his selfishness and become Earth's protector?

Integral check. Is partial fractions the only way?

Arizona laws regarding ownership of ground glassware for chemistry usage

How to play songs that contain one guitar when we have two or more guitarists?

How to know if I am a 'Real Developer'

How do I add a strong "onion flavor" to the biryani (in restaurant style)?

Rudeness by being polite

Failing PhD, how to go forward?

Can you wish for more wishes from an Efreeti bound to service via an Efreeti Bottle?

Is it possible to detect 100% of SQLi with a simple regex?

Short story where Earth is given a racist governor who likes species of a certain color

Is opening a file faster than reading variable content?

Discouraging missile alpha strikes

Why is Bernie Sanders maximum accepted donation on actblue $5600?

Sing Baby Shark

Does an intelligent undead have a soul in 5e D&D?



Stream.findFirst different than Optional.of?


Differences between HashMap and Hashtable?What is the difference between public, protected, package-private and private in Java?Difference between StringBuilder and StringBufferDifference between wait() and sleep()Difference between HashMap, LinkedHashMap and TreeMapWhat's the difference between @Component, @Repository & @Service annotations in Spring?Why is it faster to process a sorted array than an unsorted array?Why is printing “B” dramatically slower than printing “#”?What's the difference between map and flatMap methods in Java 8?Why use Optional.of over Optional.ofNullable?













6















Lets say I have two classes and two methods:



class Scratch {
private class A{}
private class B extends A{}

public Optional<A> getItems(List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}

public Optional<A> getItems2(List<String> items){
return Optional.of(
items.stream()
.map(s -> new B())
.findFirst()
.get()
);
}
}


Why does getItems2 compile while getItems gives compiler error



incompatible types: java.util.Optional<Scratch.B> cannot be converted to java.util.Optional<Scratch.A>


So when I get the value of the Optional returned by findFirst and wrap it again with Optional.of the compiler recognizes the inheritance but not if I use directly the result of findFirst.










share|improve this question

























  • Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

    – nullpointer
    2 hours ago













  • @nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

    – Holger
    59 mins ago
















6















Lets say I have two classes and two methods:



class Scratch {
private class A{}
private class B extends A{}

public Optional<A> getItems(List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}

public Optional<A> getItems2(List<String> items){
return Optional.of(
items.stream()
.map(s -> new B())
.findFirst()
.get()
);
}
}


Why does getItems2 compile while getItems gives compiler error



incompatible types: java.util.Optional<Scratch.B> cannot be converted to java.util.Optional<Scratch.A>


So when I get the value of the Optional returned by findFirst and wrap it again with Optional.of the compiler recognizes the inheritance but not if I use directly the result of findFirst.










share|improve this question

























  • Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

    – nullpointer
    2 hours ago













  • @nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

    – Holger
    59 mins ago














6












6








6


1






Lets say I have two classes and two methods:



class Scratch {
private class A{}
private class B extends A{}

public Optional<A> getItems(List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}

public Optional<A> getItems2(List<String> items){
return Optional.of(
items.stream()
.map(s -> new B())
.findFirst()
.get()
);
}
}


Why does getItems2 compile while getItems gives compiler error



incompatible types: java.util.Optional<Scratch.B> cannot be converted to java.util.Optional<Scratch.A>


So when I get the value of the Optional returned by findFirst and wrap it again with Optional.of the compiler recognizes the inheritance but not if I use directly the result of findFirst.










share|improve this question
















Lets say I have two classes and two methods:



class Scratch {
private class A{}
private class B extends A{}

public Optional<A> getItems(List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}

public Optional<A> getItems2(List<String> items){
return Optional.of(
items.stream()
.map(s -> new B())
.findFirst()
.get()
);
}
}


Why does getItems2 compile while getItems gives compiler error



incompatible types: java.util.Optional<Scratch.B> cannot be converted to java.util.Optional<Scratch.A>


So when I get the value of the Optional returned by findFirst and wrap it again with Optional.of the compiler recognizes the inheritance but not if I use directly the result of findFirst.







java java-stream optional






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 42 mins ago









Stefan Zobel

2,44031828




2,44031828










asked 2 hours ago









user1571117user1571117

6917




6917













  • Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

    – nullpointer
    2 hours ago













  • @nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

    – Holger
    59 mins ago



















  • Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

    – nullpointer
    2 hours ago













  • @nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

    – Holger
    59 mins ago

















Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

– nullpointer
2 hours ago







Simpler to reproduce Optional<A> a = Optional.of(new B()); Optional<A> b = Stream.of(new B()).findFirst(); if I get you correct. Mostly, the reason is type inferred from the context for Optional.of as its signature implies <T> Optional<T> of(T value)

– nullpointer
2 hours ago















@nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

– Holger
59 mins ago





@nullpointer yes, you’ve created the minimal example, but I suppose, the examples of the question are closer to the OP’s original code.

– Holger
59 mins ago












5 Answers
5






active

oldest

votes


















4














The issue you have is with inheritance for generics.
Optional< B > doesn't extend Optional< A >, so it can't be returned as such.



I'd imagine that something like this:



public Optional<? extends A> getItems( List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}


Or:



public Optional<?> getItems( List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}


Would work fine, depending on your needs.



Edit: escaping some characters






share|improve this answer
























  • I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

    – user1571117
    2 hours ago






  • 1





    There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

    – Holger
    1 hour ago



















3














An Optional<B> is not a sub-class of Optional<A>.



In the first case, you have a Stream<B>, so findFirst returns an Optional<B>, which cannot be converted to an Optional<A>.



In the second case, you have a stream pipeline that returns an instance of B. When you pass that instance to Optional.of(), the compiler sees that the return type of the method is Optional<A>, so Optional.of() returns an Optional<A> (since an Optional<A> can hold an instance of B as its value (since B extends A)).






share|improve this answer































    2














    If the class B inherits class A, that doesn't mean Optional inherits Optional. Optional is a different class.






    share|improve this answer































      2














      Look at this similar example:



      Optional<A> optA = Optional.of(new B()); //OK
      Optional<B> optB = Optional.of(new B()); //OK
      Optional<A> optA2 = optB; //doesn't compile


      You can make the second method fail by rewriting it as:



      public Optional<A> getItems2(List<String> items) {
      return Optional.<B>of(items.stream().map(s -> new B()).findFirst().get());
      }


      This is simply because generic types are invariant.





      Why the difference? See the declaration of Optional.of:



      public static <T> Optional<T> of(T value) {
      return new Optional<>(value);
      }


      The type of the optional is picked up from the target of the assignment (or return type in this case).



      And Stream.findFirst():



      //T comes from Stream<T>, it's not a generic method parameter
      Optional<T> findFirst();


      In this case, however, return items.stream().map(s -> new B()).findFirst(); doesn't type the result of .findFirst() based on the declared return type of getItems (T is strictly based on the type argument of Stream<T>)






      share|improve this answer

































        2














        An Optional<B> is not a subtype of Optional<A>. Unlike other programming languages, Java’s generic type system does not know “read only types” or “output type parameters”, so it doesn’t understand that Optional<B> only provides an instance of B and could work at places where an Optional<A> is required.



        When we write a statement like



        Optional<A> o = Optional.of(new B());


        Java’s type inference uses the target type to determine that we want



        Optional<A> o = Optional.<A>of(new B());


        which is valid as new B() can be used where an instance of A is required.



        The same applies to



        return Optional.of(
        items.stream()
        .map(s -> new B())
        .findFirst()
        .get()
        );


        where the method’s declared return type is used to infer the type arguments to the Optional.of invocation and passing the result of get(), an instance of B, where A is required, is valid.



        Unfortunately, this target type inference doesn’t work through chained invocations, so for



        return items.stream()
        .map(s -> new B())
        .findFirst();


        it is not used for the map call. So for the map call, the type inference uses the type of new B() and its result type will be Stream<B>. The second problem is that findFirst() is not generic, calling it on a Stream<T> invariably produces a Optional<T> (and Java’s generics does not allow to declare a type variable like <R super T>, so it is not even possible to produce an Optional<R> with the desired type here).



        → The solution is to provide an explicit type for the map call:



        public Optional<A> getItems(List<String> items){
        return items.stream()
        .<A>map(s -> new B())
        .findFirst();
        }


        Just for completeness, as said, findFirst() is not generic and hence, can’t use the target type. Chaining a generic method allowing a type change would also fix the problem:



        public Optional<A> getItems(List<String> items){
        return items.stream()
        .map(s -> new B())
        .findFirst()
        .map(Function.identity());
        }


        But I recommend using the solution of providing an explicit type for the map invocation.






        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%2f54800943%2fstream-findfirst-different-than-optional-of%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          4














          The issue you have is with inheritance for generics.
          Optional< B > doesn't extend Optional< A >, so it can't be returned as such.



          I'd imagine that something like this:



          public Optional<? extends A> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Or:



          public Optional<?> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Would work fine, depending on your needs.



          Edit: escaping some characters






          share|improve this answer
























          • I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

            – user1571117
            2 hours ago






          • 1





            There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

            – Holger
            1 hour ago
















          4














          The issue you have is with inheritance for generics.
          Optional< B > doesn't extend Optional< A >, so it can't be returned as such.



          I'd imagine that something like this:



          public Optional<? extends A> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Or:



          public Optional<?> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Would work fine, depending on your needs.



          Edit: escaping some characters






          share|improve this answer
























          • I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

            – user1571117
            2 hours ago






          • 1





            There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

            – Holger
            1 hour ago














          4












          4








          4







          The issue you have is with inheritance for generics.
          Optional< B > doesn't extend Optional< A >, so it can't be returned as such.



          I'd imagine that something like this:



          public Optional<? extends A> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Or:



          public Optional<?> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Would work fine, depending on your needs.



          Edit: escaping some characters






          share|improve this answer













          The issue you have is with inheritance for generics.
          Optional< B > doesn't extend Optional< A >, so it can't be returned as such.



          I'd imagine that something like this:



          public Optional<? extends A> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Or:



          public Optional<?> getItems( List<String> items){
          return items.stream()
          .map(s -> new B())
          .findFirst();
          }


          Would work fine, depending on your needs.



          Edit: escaping some characters







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 hours ago









          WorthlessWorthless

          42716




          42716













          • I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

            – user1571117
            2 hours ago






          • 1





            There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

            – Holger
            1 hour ago



















          • I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

            – user1571117
            2 hours ago






          • 1





            There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

            – Holger
            1 hour ago

















          I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

          – user1571117
          2 hours ago





          I will accept this answer as it also provides the information how the first method would work (althogh I did not explicitely asked I am happy with the solution)

          – user1571117
          2 hours ago




          1




          1





          There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

          – Holger
          1 hour ago





          There’s a guideline for Generics use and it says: “Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards” and from my practical experience, it’s a good advice. After all, returning Optional<A> can be easily achieved, see this answer.

          – Holger
          1 hour ago













          3














          An Optional<B> is not a sub-class of Optional<A>.



          In the first case, you have a Stream<B>, so findFirst returns an Optional<B>, which cannot be converted to an Optional<A>.



          In the second case, you have a stream pipeline that returns an instance of B. When you pass that instance to Optional.of(), the compiler sees that the return type of the method is Optional<A>, so Optional.of() returns an Optional<A> (since an Optional<A> can hold an instance of B as its value (since B extends A)).






          share|improve this answer




























            3














            An Optional<B> is not a sub-class of Optional<A>.



            In the first case, you have a Stream<B>, so findFirst returns an Optional<B>, which cannot be converted to an Optional<A>.



            In the second case, you have a stream pipeline that returns an instance of B. When you pass that instance to Optional.of(), the compiler sees that the return type of the method is Optional<A>, so Optional.of() returns an Optional<A> (since an Optional<A> can hold an instance of B as its value (since B extends A)).






            share|improve this answer


























              3












              3








              3







              An Optional<B> is not a sub-class of Optional<A>.



              In the first case, you have a Stream<B>, so findFirst returns an Optional<B>, which cannot be converted to an Optional<A>.



              In the second case, you have a stream pipeline that returns an instance of B. When you pass that instance to Optional.of(), the compiler sees that the return type of the method is Optional<A>, so Optional.of() returns an Optional<A> (since an Optional<A> can hold an instance of B as its value (since B extends A)).






              share|improve this answer













              An Optional<B> is not a sub-class of Optional<A>.



              In the first case, you have a Stream<B>, so findFirst returns an Optional<B>, which cannot be converted to an Optional<A>.



              In the second case, you have a stream pipeline that returns an instance of B. When you pass that instance to Optional.of(), the compiler sees that the return type of the method is Optional<A>, so Optional.of() returns an Optional<A> (since an Optional<A> can hold an instance of B as its value (since B extends A)).







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 2 hours ago









              EranEran

              286k37466554




              286k37466554























                  2














                  If the class B inherits class A, that doesn't mean Optional inherits Optional. Optional is a different class.






                  share|improve this answer




























                    2














                    If the class B inherits class A, that doesn't mean Optional inherits Optional. Optional is a different class.






                    share|improve this answer


























                      2












                      2








                      2







                      If the class B inherits class A, that doesn't mean Optional inherits Optional. Optional is a different class.






                      share|improve this answer













                      If the class B inherits class A, that doesn't mean Optional inherits Optional. Optional is a different class.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 2 hours ago









                      Vinay AvasthiVinay Avasthi

                      34417




                      34417























                          2














                          Look at this similar example:



                          Optional<A> optA = Optional.of(new B()); //OK
                          Optional<B> optB = Optional.of(new B()); //OK
                          Optional<A> optA2 = optB; //doesn't compile


                          You can make the second method fail by rewriting it as:



                          public Optional<A> getItems2(List<String> items) {
                          return Optional.<B>of(items.stream().map(s -> new B()).findFirst().get());
                          }


                          This is simply because generic types are invariant.





                          Why the difference? See the declaration of Optional.of:



                          public static <T> Optional<T> of(T value) {
                          return new Optional<>(value);
                          }


                          The type of the optional is picked up from the target of the assignment (or return type in this case).



                          And Stream.findFirst():



                          //T comes from Stream<T>, it's not a generic method parameter
                          Optional<T> findFirst();


                          In this case, however, return items.stream().map(s -> new B()).findFirst(); doesn't type the result of .findFirst() based on the declared return type of getItems (T is strictly based on the type argument of Stream<T>)






                          share|improve this answer






























                            2














                            Look at this similar example:



                            Optional<A> optA = Optional.of(new B()); //OK
                            Optional<B> optB = Optional.of(new B()); //OK
                            Optional<A> optA2 = optB; //doesn't compile


                            You can make the second method fail by rewriting it as:



                            public Optional<A> getItems2(List<String> items) {
                            return Optional.<B>of(items.stream().map(s -> new B()).findFirst().get());
                            }


                            This is simply because generic types are invariant.





                            Why the difference? See the declaration of Optional.of:



                            public static <T> Optional<T> of(T value) {
                            return new Optional<>(value);
                            }


                            The type of the optional is picked up from the target of the assignment (or return type in this case).



                            And Stream.findFirst():



                            //T comes from Stream<T>, it's not a generic method parameter
                            Optional<T> findFirst();


                            In this case, however, return items.stream().map(s -> new B()).findFirst(); doesn't type the result of .findFirst() based on the declared return type of getItems (T is strictly based on the type argument of Stream<T>)






                            share|improve this answer




























                              2












                              2








                              2







                              Look at this similar example:



                              Optional<A> optA = Optional.of(new B()); //OK
                              Optional<B> optB = Optional.of(new B()); //OK
                              Optional<A> optA2 = optB; //doesn't compile


                              You can make the second method fail by rewriting it as:



                              public Optional<A> getItems2(List<String> items) {
                              return Optional.<B>of(items.stream().map(s -> new B()).findFirst().get());
                              }


                              This is simply because generic types are invariant.





                              Why the difference? See the declaration of Optional.of:



                              public static <T> Optional<T> of(T value) {
                              return new Optional<>(value);
                              }


                              The type of the optional is picked up from the target of the assignment (or return type in this case).



                              And Stream.findFirst():



                              //T comes from Stream<T>, it's not a generic method parameter
                              Optional<T> findFirst();


                              In this case, however, return items.stream().map(s -> new B()).findFirst(); doesn't type the result of .findFirst() based on the declared return type of getItems (T is strictly based on the type argument of Stream<T>)






                              share|improve this answer















                              Look at this similar example:



                              Optional<A> optA = Optional.of(new B()); //OK
                              Optional<B> optB = Optional.of(new B()); //OK
                              Optional<A> optA2 = optB; //doesn't compile


                              You can make the second method fail by rewriting it as:



                              public Optional<A> getItems2(List<String> items) {
                              return Optional.<B>of(items.stream().map(s -> new B()).findFirst().get());
                              }


                              This is simply because generic types are invariant.





                              Why the difference? See the declaration of Optional.of:



                              public static <T> Optional<T> of(T value) {
                              return new Optional<>(value);
                              }


                              The type of the optional is picked up from the target of the assignment (or return type in this case).



                              And Stream.findFirst():



                              //T comes from Stream<T>, it's not a generic method parameter
                              Optional<T> findFirst();


                              In this case, however, return items.stream().map(s -> new B()).findFirst(); doesn't type the result of .findFirst() based on the declared return type of getItems (T is strictly based on the type argument of Stream<T>)







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 2 hours ago

























                              answered 2 hours ago









                              ernest_kernest_k

                              22.6k42546




                              22.6k42546























                                  2














                                  An Optional<B> is not a subtype of Optional<A>. Unlike other programming languages, Java’s generic type system does not know “read only types” or “output type parameters”, so it doesn’t understand that Optional<B> only provides an instance of B and could work at places where an Optional<A> is required.



                                  When we write a statement like



                                  Optional<A> o = Optional.of(new B());


                                  Java’s type inference uses the target type to determine that we want



                                  Optional<A> o = Optional.<A>of(new B());


                                  which is valid as new B() can be used where an instance of A is required.



                                  The same applies to



                                  return Optional.of(
                                  items.stream()
                                  .map(s -> new B())
                                  .findFirst()
                                  .get()
                                  );


                                  where the method’s declared return type is used to infer the type arguments to the Optional.of invocation and passing the result of get(), an instance of B, where A is required, is valid.



                                  Unfortunately, this target type inference doesn’t work through chained invocations, so for



                                  return items.stream()
                                  .map(s -> new B())
                                  .findFirst();


                                  it is not used for the map call. So for the map call, the type inference uses the type of new B() and its result type will be Stream<B>. The second problem is that findFirst() is not generic, calling it on a Stream<T> invariably produces a Optional<T> (and Java’s generics does not allow to declare a type variable like <R super T>, so it is not even possible to produce an Optional<R> with the desired type here).



                                  → The solution is to provide an explicit type for the map call:



                                  public Optional<A> getItems(List<String> items){
                                  return items.stream()
                                  .<A>map(s -> new B())
                                  .findFirst();
                                  }


                                  Just for completeness, as said, findFirst() is not generic and hence, can’t use the target type. Chaining a generic method allowing a type change would also fix the problem:



                                  public Optional<A> getItems(List<String> items){
                                  return items.stream()
                                  .map(s -> new B())
                                  .findFirst()
                                  .map(Function.identity());
                                  }


                                  But I recommend using the solution of providing an explicit type for the map invocation.






                                  share|improve this answer






























                                    2














                                    An Optional<B> is not a subtype of Optional<A>. Unlike other programming languages, Java’s generic type system does not know “read only types” or “output type parameters”, so it doesn’t understand that Optional<B> only provides an instance of B and could work at places where an Optional<A> is required.



                                    When we write a statement like



                                    Optional<A> o = Optional.of(new B());


                                    Java’s type inference uses the target type to determine that we want



                                    Optional<A> o = Optional.<A>of(new B());


                                    which is valid as new B() can be used where an instance of A is required.



                                    The same applies to



                                    return Optional.of(
                                    items.stream()
                                    .map(s -> new B())
                                    .findFirst()
                                    .get()
                                    );


                                    where the method’s declared return type is used to infer the type arguments to the Optional.of invocation and passing the result of get(), an instance of B, where A is required, is valid.



                                    Unfortunately, this target type inference doesn’t work through chained invocations, so for



                                    return items.stream()
                                    .map(s -> new B())
                                    .findFirst();


                                    it is not used for the map call. So for the map call, the type inference uses the type of new B() and its result type will be Stream<B>. The second problem is that findFirst() is not generic, calling it on a Stream<T> invariably produces a Optional<T> (and Java’s generics does not allow to declare a type variable like <R super T>, so it is not even possible to produce an Optional<R> with the desired type here).



                                    → The solution is to provide an explicit type for the map call:



                                    public Optional<A> getItems(List<String> items){
                                    return items.stream()
                                    .<A>map(s -> new B())
                                    .findFirst();
                                    }


                                    Just for completeness, as said, findFirst() is not generic and hence, can’t use the target type. Chaining a generic method allowing a type change would also fix the problem:



                                    public Optional<A> getItems(List<String> items){
                                    return items.stream()
                                    .map(s -> new B())
                                    .findFirst()
                                    .map(Function.identity());
                                    }


                                    But I recommend using the solution of providing an explicit type for the map invocation.






                                    share|improve this answer




























                                      2












                                      2








                                      2







                                      An Optional<B> is not a subtype of Optional<A>. Unlike other programming languages, Java’s generic type system does not know “read only types” or “output type parameters”, so it doesn’t understand that Optional<B> only provides an instance of B and could work at places where an Optional<A> is required.



                                      When we write a statement like



                                      Optional<A> o = Optional.of(new B());


                                      Java’s type inference uses the target type to determine that we want



                                      Optional<A> o = Optional.<A>of(new B());


                                      which is valid as new B() can be used where an instance of A is required.



                                      The same applies to



                                      return Optional.of(
                                      items.stream()
                                      .map(s -> new B())
                                      .findFirst()
                                      .get()
                                      );


                                      where the method’s declared return type is used to infer the type arguments to the Optional.of invocation and passing the result of get(), an instance of B, where A is required, is valid.



                                      Unfortunately, this target type inference doesn’t work through chained invocations, so for



                                      return items.stream()
                                      .map(s -> new B())
                                      .findFirst();


                                      it is not used for the map call. So for the map call, the type inference uses the type of new B() and its result type will be Stream<B>. The second problem is that findFirst() is not generic, calling it on a Stream<T> invariably produces a Optional<T> (and Java’s generics does not allow to declare a type variable like <R super T>, so it is not even possible to produce an Optional<R> with the desired type here).



                                      → The solution is to provide an explicit type for the map call:



                                      public Optional<A> getItems(List<String> items){
                                      return items.stream()
                                      .<A>map(s -> new B())
                                      .findFirst();
                                      }


                                      Just for completeness, as said, findFirst() is not generic and hence, can’t use the target type. Chaining a generic method allowing a type change would also fix the problem:



                                      public Optional<A> getItems(List<String> items){
                                      return items.stream()
                                      .map(s -> new B())
                                      .findFirst()
                                      .map(Function.identity());
                                      }


                                      But I recommend using the solution of providing an explicit type for the map invocation.






                                      share|improve this answer















                                      An Optional<B> is not a subtype of Optional<A>. Unlike other programming languages, Java’s generic type system does not know “read only types” or “output type parameters”, so it doesn’t understand that Optional<B> only provides an instance of B and could work at places where an Optional<A> is required.



                                      When we write a statement like



                                      Optional<A> o = Optional.of(new B());


                                      Java’s type inference uses the target type to determine that we want



                                      Optional<A> o = Optional.<A>of(new B());


                                      which is valid as new B() can be used where an instance of A is required.



                                      The same applies to



                                      return Optional.of(
                                      items.stream()
                                      .map(s -> new B())
                                      .findFirst()
                                      .get()
                                      );


                                      where the method’s declared return type is used to infer the type arguments to the Optional.of invocation and passing the result of get(), an instance of B, where A is required, is valid.



                                      Unfortunately, this target type inference doesn’t work through chained invocations, so for



                                      return items.stream()
                                      .map(s -> new B())
                                      .findFirst();


                                      it is not used for the map call. So for the map call, the type inference uses the type of new B() and its result type will be Stream<B>. The second problem is that findFirst() is not generic, calling it on a Stream<T> invariably produces a Optional<T> (and Java’s generics does not allow to declare a type variable like <R super T>, so it is not even possible to produce an Optional<R> with the desired type here).



                                      → The solution is to provide an explicit type for the map call:



                                      public Optional<A> getItems(List<String> items){
                                      return items.stream()
                                      .<A>map(s -> new B())
                                      .findFirst();
                                      }


                                      Just for completeness, as said, findFirst() is not generic and hence, can’t use the target type. Chaining a generic method allowing a type change would also fix the problem:



                                      public Optional<A> getItems(List<String> items){
                                      return items.stream()
                                      .map(s -> new B())
                                      .findFirst()
                                      .map(Function.identity());
                                      }


                                      But I recommend using the solution of providing an explicit type for the map invocation.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited 5 mins ago

























                                      answered 1 hour ago









                                      HolgerHolger

                                      167k23237450




                                      167k23237450






























                                          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%2f54800943%2fstream-findfirst-different-than-optional-of%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

                                          Parapolítica Índice Antecedentes El escándalo Proceso judicial Consecuencias Véase...

                                          How to remove border from elements in the last row?Targeting flex items on the last rowHow to vertically wrap...

                                          How does insurance birth control work in the United States?How does the Social Security Work in United...