Java 8 stream API orElse usage











up vote
12
down vote

favorite
2












What I'm trying to do is to filter the list, then map it and use orElse if null and then collect it back to the list. Now I can achieve it this way:



return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> {
if(user.getData() != null) {
return user.getData();
}
return Collections.emptyMap();
}
)
.collect(Collectors.toList())
;


But the question is: how can I make this structure better and why can I not use orElse in this case?










share|improve this question




















  • 2




    Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
    – Flown
    yesterday












  • What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
    – nullpointer
    yesterday






  • 3




    getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
    – Ole V.V.
    yesterday










  • I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
    – nullpointer
    yesterday








  • 1




    @nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
    – Mykyta Bezverkhyi
    yesterday















up vote
12
down vote

favorite
2












What I'm trying to do is to filter the list, then map it and use orElse if null and then collect it back to the list. Now I can achieve it this way:



return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> {
if(user.getData() != null) {
return user.getData();
}
return Collections.emptyMap();
}
)
.collect(Collectors.toList())
;


But the question is: how can I make this structure better and why can I not use orElse in this case?










share|improve this question




















  • 2




    Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
    – Flown
    yesterday












  • What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
    – nullpointer
    yesterday






  • 3




    getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
    – Ole V.V.
    yesterday










  • I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
    – nullpointer
    yesterday








  • 1




    @nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
    – Mykyta Bezverkhyi
    yesterday













up vote
12
down vote

favorite
2









up vote
12
down vote

favorite
2






2





What I'm trying to do is to filter the list, then map it and use orElse if null and then collect it back to the list. Now I can achieve it this way:



return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> {
if(user.getData() != null) {
return user.getData();
}
return Collections.emptyMap();
}
)
.collect(Collectors.toList())
;


But the question is: how can I make this structure better and why can I not use orElse in this case?










share|improve this question















What I'm trying to do is to filter the list, then map it and use orElse if null and then collect it back to the list. Now I can achieve it this way:



return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> {
if(user.getData() != null) {
return user.getData();
}
return Collections.emptyMap();
}
)
.collect(Collectors.toList())
;


But the question is: how can I make this structure better and why can I not use orElse in this case?







java java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









candied_orange

4,1271647




4,1271647










asked yesterday









Mykyta Bezverkhyi

696




696








  • 2




    Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
    – Flown
    yesterday












  • What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
    – nullpointer
    yesterday






  • 3




    getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
    – Ole V.V.
    yesterday










  • I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
    – nullpointer
    yesterday








  • 1




    @nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
    – Mykyta Bezverkhyi
    yesterday














  • 2




    Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
    – Flown
    yesterday












  • What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
    – nullpointer
    yesterday






  • 3




    getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
    – Ole V.V.
    yesterday










  • I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
    – nullpointer
    yesterday








  • 1




    @nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
    – Mykyta Bezverkhyi
    yesterday








2




2




Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
– Flown
yesterday






Maybe your User::getData should return a Optional<Map<K, V>> then you can apply ...map(user -> user.getData().orElseGet(this::emptyMap)).....
– Flown
yesterday














What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
– nullpointer
yesterday




What's the emptyMap in the question what are getData and getId, a basic object schema would be helpful unless you just want people to keep speculating.
– nullpointer
yesterday




3




3




getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
– Ole V.V.
yesterday




getData should best return an empty collection instead of null. Returning null for no elements is bad practice.
– Ole V.V.
yesterday












I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
– nullpointer
yesterday






I highly doubt that you might just be looking for users.stream() .filter(user -> id.equals(user.getId()) && user.getData() != null) .map(User::getData) .collect(Collectors.toList());... but then the question isn't clear enough to say what emptyMap is or what is the eventual return type of your statement is!! I mean who knows if there is an Optional even involved in the above operation at all.
– nullpointer
yesterday






1




1




@nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
– Mykyta Bezverkhyi
yesterday




@nullpointer I got your point, I don't need it to be out, I need the same list size to use it after
– Mykyta Bezverkhyi
yesterday












5 Answers
5






active

oldest

votes

















up vote
13
down vote



accepted










It might be more readable with ternary conditional operator:



return users.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> (user.getData() != null)
? user.getData()
: emptyMap()
)
.collect(Collectors.toList())
;


In order to use orElse you'll have to create an Optional that wraps user.getData(). I'm not sure that's a good idea.



If you insist on using orElse (or even better, orElseGet, to avoid evaluating emptyMap() when it's not required), it can look like this:



return users.stream()
.filter(user -> id.equals(user.getId()))
.map(
user -> Optional.ofNullable(
user.getData()
).orElseGet(
() -> emptyMap()
)
)
.collect(Collectors.toList())
;





share|improve this answer























  • since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
    – Mykyta Bezverkhyi
    yesterday






  • 1




    Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
    – nullpointer
    yesterday








  • 1




    @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
    – Mykyta Bezverkhyi
    yesterday






  • 5




    Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
    – Holger
    yesterday








  • 1




    ...or even Objects.requireNonNullElseGet
    – Hulk
    yesterday


















up vote
5
down vote













As I pointed out in the comments as well and I highly doubt that you might just be looking for the following



users
.stream()
.filter(
user -> id.equals(user.getId())
&& (user.getData() != null)
)
.map(User::getData)
.collect(Collectors.toList())
;


But then the question isn't clear enough to say what is the eventual return type of your statement is or what is the emptyMap used in your code! Hence I highly doubt, if you even need an Optional API in first place for this operation.



Note: The above-stated solution does assume that emptyMap is Collections.emptyMap which I am not sure why would one want to collect in a data structure which is denoted as List<Map<K,V>>.






share|improve this answer























  • .filter(user -> user != null && ...)
    – Andrew Tobilko
    yesterday










  • @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
    – nullpointer
    yesterday












  • Thanks for your answer, it's not something that I need, and sorry if my question is not clear
    – Mykyta Bezverkhyi
    yesterday






  • 1




    @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
    – nullpointer
    yesterday




















up vote
1
down vote













What about:



return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(user -> user.getData())
.filter(Objects::nonNull)
.collect(Collectors.toList())
;


Excerpt from Objects::nonNull:




API Note:
This method exists to be used as a Predicate, filter(Objects::nonNull)







share|improve this answer





















  • I nominate this as the most readable thing here.
    – candied_orange
    4 hours ago


















up vote
1
down vote













Use Objects::requireNonNullElse!



I would advise of of two things to make the code more readable. I would not, however, artificially introduce an Optional.





First option: Objects::requireNonNullElse in a separate method



List<Map<?, ?> bar() {
//...

return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(User::getData)
.map(Foo::nullSafeMap)
.collect(Collectors.toList())
;
}

private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
return Objects.requireNonNullElse(map, Collections.emptyMap());
}


Here, you would use Objects::requireNonNullElse, which returns the object passed in the first parameter if it is not null, and the object passed as the second parameter if the first parameter is null. Having a separate method allows for a method reference to be passed to Stream::map, but requires you to first map the User instances to their data Map.





Second option: Inline Objects::requireNonNullElse



List<Map<?, ?> bar() {
//...

return users
.stream()
.filter(user -> id.equals(user.getId()))
.map(User::getData)
.map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
.collect(Collectors.toList())
;
}


If you do not want a separate method to do just this single task, you can inline the method and optionally even remove the first mapping in favor of .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap())), but I would advise against this. Don't be afraid to have multiple calls to Stream::map if it makes the code more readable.





Conclusion



I would prefer the first option as it makes the code very readable: You know that you map the User instances to the data, then you make that data null safe.



The second option is alright, but suffers from a very long line that might be confusing on the first glance. It is much better than having a multi-line lambda though. I would avoid multi-line lambdas at all costs and always extract their contents into a separate method.



One thing you might be able to improve upon is the method name nullSafeMap, as to avoid confusion between Stream::map and java.util.Map.



Note that you don't need to use Objects::requireNonNullElseGet since Collections::emptyMap is a lightweight method that only casts and returns a constant:



public static final <K,V> Map<K,V> emptyMap() {
return (Map<K,V>) EMPTY_MAP;
}


Objects::requireNonNullElseGet is made for default objects whose retrieval or creation is heavyweight.






share|improve this answer






























    up vote
    1
    down vote














    How can I make this structure better




    Method 1:



    return users.stream()
    .filter(user -> id.equals(user.getId()))
    .map(
    user -> (user.getData() != null)
    ? user.getData()
    : emptyMap()
    )
    .collect(Collectors.toList())
    ;


    Method 2:



    Make your getData return an Optional: user -> user.getData().orElse(emptyMap())



    Method 3:



    As @Eran said: Optional.ofNullable then use orElse(emptyMap()) like above: user -> Optional.ofNullable(user.getData()).orElse(emptyMap())




    Why I cannot use orElse in this case?




    Not sure what orElse you mean




    1. If user.getData() returns null, it should be wrapped to an Optional to call orElse.


    2. The stream's findAny().orElse operates on the stream's result itself. But what you need here is to check if user.getData() exists. So you can not use stream's result's orElse directly.







    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%2f53609590%2fjava-8-stream-api-orelse-usage%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








      up vote
      13
      down vote



      accepted










      It might be more readable with ternary conditional operator:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> (user.getData() != null)
      ? user.getData()
      : emptyMap()
      )
      .collect(Collectors.toList())
      ;


      In order to use orElse you'll have to create an Optional that wraps user.getData(). I'm not sure that's a good idea.



      If you insist on using orElse (or even better, orElseGet, to avoid evaluating emptyMap() when it's not required), it can look like this:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> Optional.ofNullable(
      user.getData()
      ).orElseGet(
      () -> emptyMap()
      )
      )
      .collect(Collectors.toList())
      ;





      share|improve this answer























      • since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
        – Mykyta Bezverkhyi
        yesterday






      • 1




        Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
        – nullpointer
        yesterday








      • 1




        @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
        – Mykyta Bezverkhyi
        yesterday






      • 5




        Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
        – Holger
        yesterday








      • 1




        ...or even Objects.requireNonNullElseGet
        – Hulk
        yesterday















      up vote
      13
      down vote



      accepted










      It might be more readable with ternary conditional operator:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> (user.getData() != null)
      ? user.getData()
      : emptyMap()
      )
      .collect(Collectors.toList())
      ;


      In order to use orElse you'll have to create an Optional that wraps user.getData(). I'm not sure that's a good idea.



      If you insist on using orElse (or even better, orElseGet, to avoid evaluating emptyMap() when it's not required), it can look like this:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> Optional.ofNullable(
      user.getData()
      ).orElseGet(
      () -> emptyMap()
      )
      )
      .collect(Collectors.toList())
      ;





      share|improve this answer























      • since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
        – Mykyta Bezverkhyi
        yesterday






      • 1




        Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
        – nullpointer
        yesterday








      • 1




        @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
        – Mykyta Bezverkhyi
        yesterday






      • 5




        Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
        – Holger
        yesterday








      • 1




        ...or even Objects.requireNonNullElseGet
        – Hulk
        yesterday













      up vote
      13
      down vote



      accepted







      up vote
      13
      down vote



      accepted






      It might be more readable with ternary conditional operator:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> (user.getData() != null)
      ? user.getData()
      : emptyMap()
      )
      .collect(Collectors.toList())
      ;


      In order to use orElse you'll have to create an Optional that wraps user.getData(). I'm not sure that's a good idea.



      If you insist on using orElse (or even better, orElseGet, to avoid evaluating emptyMap() when it's not required), it can look like this:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> Optional.ofNullable(
      user.getData()
      ).orElseGet(
      () -> emptyMap()
      )
      )
      .collect(Collectors.toList())
      ;





      share|improve this answer














      It might be more readable with ternary conditional operator:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> (user.getData() != null)
      ? user.getData()
      : emptyMap()
      )
      .collect(Collectors.toList())
      ;


      In order to use orElse you'll have to create an Optional that wraps user.getData(). I'm not sure that's a good idea.



      If you insist on using orElse (or even better, orElseGet, to avoid evaluating emptyMap() when it's not required), it can look like this:



      return users.stream()
      .filter(user -> id.equals(user.getId()))
      .map(
      user -> Optional.ofNullable(
      user.getData()
      ).orElseGet(
      () -> emptyMap()
      )
      )
      .collect(Collectors.toList())
      ;






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 4 hours ago









      candied_orange

      4,1271647




      4,1271647










      answered yesterday









      Eran

      275k36442525




      275k36442525












      • since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
        – Mykyta Bezverkhyi
        yesterday






      • 1




        Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
        – nullpointer
        yesterday








      • 1




        @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
        – Mykyta Bezverkhyi
        yesterday






      • 5




        Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
        – Holger
        yesterday








      • 1




        ...or even Objects.requireNonNullElseGet
        – Hulk
        yesterday


















      • since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
        – Mykyta Bezverkhyi
        yesterday






      • 1




        Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
        – nullpointer
        yesterday








      • 1




        @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
        – Mykyta Bezverkhyi
        yesterday






      • 5




        Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
        – Holger
        yesterday








      • 1




        ...or even Objects.requireNonNullElseGet
        – Hulk
        yesterday
















      since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
      – Mykyta Bezverkhyi
      yesterday




      since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
      – Mykyta Bezverkhyi
      yesterday




      1




      1




      Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
      – nullpointer
      yesterday






      Typo user.getDate(), should be user.getData() ... and @Eran I really doubt one should be using Optional for this use case anyway. I mean what sense would it make to add emptyMap to a List of Maps for a condition when they are actually null ?
      – nullpointer
      yesterday






      1




      1




      @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
      – Mykyta Bezverkhyi
      yesterday




      @Eran it's definitely makes sense in my case, I actually prefer Optionals just in case it looks better
      – Mykyta Bezverkhyi
      yesterday




      5




      5




      Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
      – Holger
      yesterday






      Java 9+: .map(user -> Objects.requireNonNullElse(user.getData(), emptyMap())). The ternary operator has the disadvantage that it may invoke getData() twice.
      – Holger
      yesterday






      1




      1




      ...or even Objects.requireNonNullElseGet
      – Hulk
      yesterday




      ...or even Objects.requireNonNullElseGet
      – Hulk
      yesterday












      up vote
      5
      down vote













      As I pointed out in the comments as well and I highly doubt that you might just be looking for the following



      users
      .stream()
      .filter(
      user -> id.equals(user.getId())
      && (user.getData() != null)
      )
      .map(User::getData)
      .collect(Collectors.toList())
      ;


      But then the question isn't clear enough to say what is the eventual return type of your statement is or what is the emptyMap used in your code! Hence I highly doubt, if you even need an Optional API in first place for this operation.



      Note: The above-stated solution does assume that emptyMap is Collections.emptyMap which I am not sure why would one want to collect in a data structure which is denoted as List<Map<K,V>>.






      share|improve this answer























      • .filter(user -> user != null && ...)
        – Andrew Tobilko
        yesterday










      • @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
        – nullpointer
        yesterday












      • Thanks for your answer, it's not something that I need, and sorry if my question is not clear
        – Mykyta Bezverkhyi
        yesterday






      • 1




        @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
        – nullpointer
        yesterday

















      up vote
      5
      down vote













      As I pointed out in the comments as well and I highly doubt that you might just be looking for the following



      users
      .stream()
      .filter(
      user -> id.equals(user.getId())
      && (user.getData() != null)
      )
      .map(User::getData)
      .collect(Collectors.toList())
      ;


      But then the question isn't clear enough to say what is the eventual return type of your statement is or what is the emptyMap used in your code! Hence I highly doubt, if you even need an Optional API in first place for this operation.



      Note: The above-stated solution does assume that emptyMap is Collections.emptyMap which I am not sure why would one want to collect in a data structure which is denoted as List<Map<K,V>>.






      share|improve this answer























      • .filter(user -> user != null && ...)
        – Andrew Tobilko
        yesterday










      • @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
        – nullpointer
        yesterday












      • Thanks for your answer, it's not something that I need, and sorry if my question is not clear
        – Mykyta Bezverkhyi
        yesterday






      • 1




        @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
        – nullpointer
        yesterday















      up vote
      5
      down vote










      up vote
      5
      down vote









      As I pointed out in the comments as well and I highly doubt that you might just be looking for the following



      users
      .stream()
      .filter(
      user -> id.equals(user.getId())
      && (user.getData() != null)
      )
      .map(User::getData)
      .collect(Collectors.toList())
      ;


      But then the question isn't clear enough to say what is the eventual return type of your statement is or what is the emptyMap used in your code! Hence I highly doubt, if you even need an Optional API in first place for this operation.



      Note: The above-stated solution does assume that emptyMap is Collections.emptyMap which I am not sure why would one want to collect in a data structure which is denoted as List<Map<K,V>>.






      share|improve this answer














      As I pointed out in the comments as well and I highly doubt that you might just be looking for the following



      users
      .stream()
      .filter(
      user -> id.equals(user.getId())
      && (user.getData() != null)
      )
      .map(User::getData)
      .collect(Collectors.toList())
      ;


      But then the question isn't clear enough to say what is the eventual return type of your statement is or what is the emptyMap used in your code! Hence I highly doubt, if you even need an Optional API in first place for this operation.



      Note: The above-stated solution does assume that emptyMap is Collections.emptyMap which I am not sure why would one want to collect in a data structure which is denoted as List<Map<K,V>>.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 4 hours ago









      candied_orange

      4,1271647




      4,1271647










      answered yesterday









      nullpointer

      37.4k1072145




      37.4k1072145












      • .filter(user -> user != null && ...)
        – Andrew Tobilko
        yesterday










      • @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
        – nullpointer
        yesterday












      • Thanks for your answer, it's not something that I need, and sorry if my question is not clear
        – Mykyta Bezverkhyi
        yesterday






      • 1




        @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
        – nullpointer
        yesterday




















      • .filter(user -> user != null && ...)
        – Andrew Tobilko
        yesterday










      • @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
        – nullpointer
        yesterday












      • Thanks for your answer, it's not something that I need, and sorry if my question is not clear
        – Mykyta Bezverkhyi
        yesterday






      • 1




        @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
        – nullpointer
        yesterday


















      .filter(user -> user != null && ...)
      – Andrew Tobilko
      yesterday




      .filter(user -> user != null && ...)
      – Andrew Tobilko
      yesterday












      @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
      – nullpointer
      yesterday






      @AndrewTobilko why? is a user would be null there would have been an NPE thrown for code in the question itself.. isn't it?
      – nullpointer
      yesterday














      Thanks for your answer, it's not something that I need, and sorry if my question is not clear
      – Mykyta Bezverkhyi
      yesterday




      Thanks for your answer, it's not something that I need, and sorry if my question is not clear
      – Mykyta Bezverkhyi
      yesterday




      1




      1




      @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
      – nullpointer
      yesterday






      @MykytaBezverkhyi well sure, just wanted to clarify certain things as a practice... was eventually curious to know if a List with empty Map could actually serve a good purpose in any use case. Updates to the question made it clear. :)
      – nullpointer
      yesterday












      up vote
      1
      down vote













      What about:



      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(user -> user.getData())
      .filter(Objects::nonNull)
      .collect(Collectors.toList())
      ;


      Excerpt from Objects::nonNull:




      API Note:
      This method exists to be used as a Predicate, filter(Objects::nonNull)







      share|improve this answer





















      • I nominate this as the most readable thing here.
        – candied_orange
        4 hours ago















      up vote
      1
      down vote













      What about:



      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(user -> user.getData())
      .filter(Objects::nonNull)
      .collect(Collectors.toList())
      ;


      Excerpt from Objects::nonNull:




      API Note:
      This method exists to be used as a Predicate, filter(Objects::nonNull)







      share|improve this answer





















      • I nominate this as the most readable thing here.
        – candied_orange
        4 hours ago













      up vote
      1
      down vote










      up vote
      1
      down vote









      What about:



      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(user -> user.getData())
      .filter(Objects::nonNull)
      .collect(Collectors.toList())
      ;


      Excerpt from Objects::nonNull:




      API Note:
      This method exists to be used as a Predicate, filter(Objects::nonNull)







      share|improve this answer












      What about:



      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(user -> user.getData())
      .filter(Objects::nonNull)
      .collect(Collectors.toList())
      ;


      Excerpt from Objects::nonNull:




      API Note:
      This method exists to be used as a Predicate, filter(Objects::nonNull)








      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 6 hours ago









      Illya Kysil

      684310




      684310












      • I nominate this as the most readable thing here.
        – candied_orange
        4 hours ago


















      • I nominate this as the most readable thing here.
        – candied_orange
        4 hours ago
















      I nominate this as the most readable thing here.
      – candied_orange
      4 hours ago




      I nominate this as the most readable thing here.
      – candied_orange
      4 hours ago










      up vote
      1
      down vote













      Use Objects::requireNonNullElse!



      I would advise of of two things to make the code more readable. I would not, however, artificially introduce an Optional.





      First option: Objects::requireNonNullElse in a separate method



      List<Map<?, ?> bar() {
      //...

      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(User::getData)
      .map(Foo::nullSafeMap)
      .collect(Collectors.toList())
      ;
      }

      private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
      return Objects.requireNonNullElse(map, Collections.emptyMap());
      }


      Here, you would use Objects::requireNonNullElse, which returns the object passed in the first parameter if it is not null, and the object passed as the second parameter if the first parameter is null. Having a separate method allows for a method reference to be passed to Stream::map, but requires you to first map the User instances to their data Map.





      Second option: Inline Objects::requireNonNullElse



      List<Map<?, ?> bar() {
      //...

      return users
      .stream()
      .filter(user -> id.equals(user.getId()))
      .map(User::getData)
      .map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
      .collect(Collectors.toList())
      ;
      }


      If you do not want a separate method to do just this single task, you can inline the method and optionally even remove the first mapping in favor of .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap())), but I would advise against this. Don't be afraid to have multiple calls to Stream::map if it makes the code more readable.





      Conclusion



      I would prefer the first option as it makes the code very readable: You know that you map the User instances to the data, then you make that data null safe.



      The second option is alright, but suffers from a very long line that might be confusing on the first glance. It is much better than having a multi-line lambda though. I would avoid multi-line lambdas at all costs and always extract their contents into a separate method.



      One thing you might be able to improve upon is the method name nullSafeMap, as to avoid confusion between Stream::map and java.util.Map.



      Note that you don't need to use Objects::requireNonNullElseGet since Collections::emptyMap is a lightweight method that only casts and returns a constant:



      public static final <K,V> Map<K,V> emptyMap() {
      return (Map<K,V>) EMPTY_MAP;
      }


      Objects::requireNonNullElseGet is made for default objects whose retrieval or creation is heavyweight.






      share|improve this answer



























        up vote
        1
        down vote













        Use Objects::requireNonNullElse!



        I would advise of of two things to make the code more readable. I would not, however, artificially introduce an Optional.





        First option: Objects::requireNonNullElse in a separate method



        List<Map<?, ?> bar() {
        //...

        return users
        .stream()
        .filter(user -> id.equals(user.getId()))
        .map(User::getData)
        .map(Foo::nullSafeMap)
        .collect(Collectors.toList())
        ;
        }

        private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
        return Objects.requireNonNullElse(map, Collections.emptyMap());
        }


        Here, you would use Objects::requireNonNullElse, which returns the object passed in the first parameter if it is not null, and the object passed as the second parameter if the first parameter is null. Having a separate method allows for a method reference to be passed to Stream::map, but requires you to first map the User instances to their data Map.





        Second option: Inline Objects::requireNonNullElse



        List<Map<?, ?> bar() {
        //...

        return users
        .stream()
        .filter(user -> id.equals(user.getId()))
        .map(User::getData)
        .map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
        .collect(Collectors.toList())
        ;
        }


        If you do not want a separate method to do just this single task, you can inline the method and optionally even remove the first mapping in favor of .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap())), but I would advise against this. Don't be afraid to have multiple calls to Stream::map if it makes the code more readable.





        Conclusion



        I would prefer the first option as it makes the code very readable: You know that you map the User instances to the data, then you make that data null safe.



        The second option is alright, but suffers from a very long line that might be confusing on the first glance. It is much better than having a multi-line lambda though. I would avoid multi-line lambdas at all costs and always extract their contents into a separate method.



        One thing you might be able to improve upon is the method name nullSafeMap, as to avoid confusion between Stream::map and java.util.Map.



        Note that you don't need to use Objects::requireNonNullElseGet since Collections::emptyMap is a lightweight method that only casts and returns a constant:



        public static final <K,V> Map<K,V> emptyMap() {
        return (Map<K,V>) EMPTY_MAP;
        }


        Objects::requireNonNullElseGet is made for default objects whose retrieval or creation is heavyweight.






        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          Use Objects::requireNonNullElse!



          I would advise of of two things to make the code more readable. I would not, however, artificially introduce an Optional.





          First option: Objects::requireNonNullElse in a separate method



          List<Map<?, ?> bar() {
          //...

          return users
          .stream()
          .filter(user -> id.equals(user.getId()))
          .map(User::getData)
          .map(Foo::nullSafeMap)
          .collect(Collectors.toList())
          ;
          }

          private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
          return Objects.requireNonNullElse(map, Collections.emptyMap());
          }


          Here, you would use Objects::requireNonNullElse, which returns the object passed in the first parameter if it is not null, and the object passed as the second parameter if the first parameter is null. Having a separate method allows for a method reference to be passed to Stream::map, but requires you to first map the User instances to their data Map.





          Second option: Inline Objects::requireNonNullElse



          List<Map<?, ?> bar() {
          //...

          return users
          .stream()
          .filter(user -> id.equals(user.getId()))
          .map(User::getData)
          .map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
          .collect(Collectors.toList())
          ;
          }


          If you do not want a separate method to do just this single task, you can inline the method and optionally even remove the first mapping in favor of .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap())), but I would advise against this. Don't be afraid to have multiple calls to Stream::map if it makes the code more readable.





          Conclusion



          I would prefer the first option as it makes the code very readable: You know that you map the User instances to the data, then you make that data null safe.



          The second option is alright, but suffers from a very long line that might be confusing on the first glance. It is much better than having a multi-line lambda though. I would avoid multi-line lambdas at all costs and always extract their contents into a separate method.



          One thing you might be able to improve upon is the method name nullSafeMap, as to avoid confusion between Stream::map and java.util.Map.



          Note that you don't need to use Objects::requireNonNullElseGet since Collections::emptyMap is a lightweight method that only casts and returns a constant:



          public static final <K,V> Map<K,V> emptyMap() {
          return (Map<K,V>) EMPTY_MAP;
          }


          Objects::requireNonNullElseGet is made for default objects whose retrieval or creation is heavyweight.






          share|improve this answer














          Use Objects::requireNonNullElse!



          I would advise of of two things to make the code more readable. I would not, however, artificially introduce an Optional.





          First option: Objects::requireNonNullElse in a separate method



          List<Map<?, ?> bar() {
          //...

          return users
          .stream()
          .filter(user -> id.equals(user.getId()))
          .map(User::getData)
          .map(Foo::nullSafeMap)
          .collect(Collectors.toList())
          ;
          }

          private static Map<?, ?> nullSafeMap(final Map<?, ?> map) {
          return Objects.requireNonNullElse(map, Collections.emptyMap());
          }


          Here, you would use Objects::requireNonNullElse, which returns the object passed in the first parameter if it is not null, and the object passed as the second parameter if the first parameter is null. Having a separate method allows for a method reference to be passed to Stream::map, but requires you to first map the User instances to their data Map.





          Second option: Inline Objects::requireNonNullElse



          List<Map<?, ?> bar() {
          //...

          return users
          .stream()
          .filter(user -> id.equals(user.getId()))
          .map(User::getData)
          .map(map -> Objects.requireNonNullElse(map, Collections.emptyMap()))
          .collect(Collectors.toList())
          ;
          }


          If you do not want a separate method to do just this single task, you can inline the method and optionally even remove the first mapping in favor of .map(user -> Objects.requireNonNullElse(user.getData(), Collections.emptyMap())), but I would advise against this. Don't be afraid to have multiple calls to Stream::map if it makes the code more readable.





          Conclusion



          I would prefer the first option as it makes the code very readable: You know that you map the User instances to the data, then you make that data null safe.



          The second option is alright, but suffers from a very long line that might be confusing on the first glance. It is much better than having a multi-line lambda though. I would avoid multi-line lambdas at all costs and always extract their contents into a separate method.



          One thing you might be able to improve upon is the method name nullSafeMap, as to avoid confusion between Stream::map and java.util.Map.



          Note that you don't need to use Objects::requireNonNullElseGet since Collections::emptyMap is a lightweight method that only casts and returns a constant:



          public static final <K,V> Map<K,V> emptyMap() {
          return (Map<K,V>) EMPTY_MAP;
          }


          Objects::requireNonNullElseGet is made for default objects whose retrieval or creation is heavyweight.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 4 hours ago









          candied_orange

          4,1271647




          4,1271647










          answered yesterday









          Marv

          2,56311131




          2,56311131






















              up vote
              1
              down vote














              How can I make this structure better




              Method 1:



              return users.stream()
              .filter(user -> id.equals(user.getId()))
              .map(
              user -> (user.getData() != null)
              ? user.getData()
              : emptyMap()
              )
              .collect(Collectors.toList())
              ;


              Method 2:



              Make your getData return an Optional: user -> user.getData().orElse(emptyMap())



              Method 3:



              As @Eran said: Optional.ofNullable then use orElse(emptyMap()) like above: user -> Optional.ofNullable(user.getData()).orElse(emptyMap())




              Why I cannot use orElse in this case?




              Not sure what orElse you mean




              1. If user.getData() returns null, it should be wrapped to an Optional to call orElse.


              2. The stream's findAny().orElse operates on the stream's result itself. But what you need here is to check if user.getData() exists. So you can not use stream's result's orElse directly.







              share|improve this answer



























                up vote
                1
                down vote














                How can I make this structure better




                Method 1:



                return users.stream()
                .filter(user -> id.equals(user.getId()))
                .map(
                user -> (user.getData() != null)
                ? user.getData()
                : emptyMap()
                )
                .collect(Collectors.toList())
                ;


                Method 2:



                Make your getData return an Optional: user -> user.getData().orElse(emptyMap())



                Method 3:



                As @Eran said: Optional.ofNullable then use orElse(emptyMap()) like above: user -> Optional.ofNullable(user.getData()).orElse(emptyMap())




                Why I cannot use orElse in this case?




                Not sure what orElse you mean




                1. If user.getData() returns null, it should be wrapped to an Optional to call orElse.


                2. The stream's findAny().orElse operates on the stream's result itself. But what you need here is to check if user.getData() exists. So you can not use stream's result's orElse directly.







                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote










                  How can I make this structure better




                  Method 1:



                  return users.stream()
                  .filter(user -> id.equals(user.getId()))
                  .map(
                  user -> (user.getData() != null)
                  ? user.getData()
                  : emptyMap()
                  )
                  .collect(Collectors.toList())
                  ;


                  Method 2:



                  Make your getData return an Optional: user -> user.getData().orElse(emptyMap())



                  Method 3:



                  As @Eran said: Optional.ofNullable then use orElse(emptyMap()) like above: user -> Optional.ofNullable(user.getData()).orElse(emptyMap())




                  Why I cannot use orElse in this case?




                  Not sure what orElse you mean




                  1. If user.getData() returns null, it should be wrapped to an Optional to call orElse.


                  2. The stream's findAny().orElse operates on the stream's result itself. But what you need here is to check if user.getData() exists. So you can not use stream's result's orElse directly.







                  share|improve this answer















                  How can I make this structure better




                  Method 1:



                  return users.stream()
                  .filter(user -> id.equals(user.getId()))
                  .map(
                  user -> (user.getData() != null)
                  ? user.getData()
                  : emptyMap()
                  )
                  .collect(Collectors.toList())
                  ;


                  Method 2:



                  Make your getData return an Optional: user -> user.getData().orElse(emptyMap())



                  Method 3:



                  As @Eran said: Optional.ofNullable then use orElse(emptyMap()) like above: user -> Optional.ofNullable(user.getData()).orElse(emptyMap())




                  Why I cannot use orElse in this case?




                  Not sure what orElse you mean




                  1. If user.getData() returns null, it should be wrapped to an Optional to call orElse.


                  2. The stream's findAny().orElse operates on the stream's result itself. But what you need here is to check if user.getData() exists. So you can not use stream's result's orElse directly.








                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 4 hours ago









                  candied_orange

                  4,1271647




                  4,1271647










                  answered yesterday









                  shawn

                  2,856616




                  2,856616






























                      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.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • 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%2f53609590%2fjava-8-stream-api-orelse-usage%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

                      Ellipse (mathématiques)

                      Quarter-circle Tiles

                      Mont Emei