Java 8 stream API orElse usage
up vote
12
down vote
favorite
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
|
show 7 more comments
up vote
12
down vote
favorite
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
2
Maybe yourUser::getData
should return aOptional<Map<K, V>>
then you can apply...map(user -> user.getData().orElseGet(this::emptyMap))....
.
– Flown
yesterday
What's theemptyMap
in the question what aregetData
andgetId
, 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 ofnull
. Returningnull
for no elements is bad practice.
– Ole V.V.
yesterday
I highly doubt that you might just be looking forusers.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 whatemptyMap
is or what is the eventual return type of your statement is!! I mean who knows if there is anOptional
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
|
show 7 more comments
up vote
12
down vote
favorite
up vote
12
down vote
favorite
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
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
java java-8 java-stream
edited yesterday
candied_orange
4,1271647
4,1271647
asked yesterday
Mykyta Bezverkhyi
696
696
2
Maybe yourUser::getData
should return aOptional<Map<K, V>>
then you can apply...map(user -> user.getData().orElseGet(this::emptyMap))....
.
– Flown
yesterday
What's theemptyMap
in the question what aregetData
andgetId
, 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 ofnull
. Returningnull
for no elements is bad practice.
– Ole V.V.
yesterday
I highly doubt that you might just be looking forusers.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 whatemptyMap
is or what is the eventual return type of your statement is!! I mean who knows if there is anOptional
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
|
show 7 more comments
2
Maybe yourUser::getData
should return aOptional<Map<K, V>>
then you can apply...map(user -> user.getData().orElseGet(this::emptyMap))....
.
– Flown
yesterday
What's theemptyMap
in the question what aregetData
andgetId
, 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 ofnull
. Returningnull
for no elements is bad practice.
– Ole V.V.
yesterday
I highly doubt that you might just be looking forusers.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 whatemptyMap
is or what is the eventual return type of your statement is!! I mean who knows if there is anOptional
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
|
show 7 more comments
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())
;
since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
– Mykyta Bezverkhyi
yesterday
1
Typouser.getDate()
, should beuser.getData()
... and @Eran I really doubt one should be usingOptional
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 invokegetData()
twice.
– Holger
yesterday
1
...or even Objects.requireNonNullElseGet
– Hulk
yesterday
|
show 3 more comments
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>>
.
.filter(user -> user != null && ...)
– Andrew Tobilko
yesterday
@AndrewTobilko why? is auser
would benull
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
add a comment |
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 aPredicate
,filter(Objects::nonNull)
I nominate this as the most readable thing here.
– candied_orange
4 hours ago
add a comment |
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.
add a comment |
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
If
user.getData()
returnsnull
, it should be wrapped to anOptional
to callorElse
.The stream's
findAny().orElse
operates on the stream's result itself. But what you need here is to check ifuser.getData()
exists. So you can not use stream's result'sorElse
directly.
add a comment |
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())
;
since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
– Mykyta Bezverkhyi
yesterday
1
Typouser.getDate()
, should beuser.getData()
... and @Eran I really doubt one should be usingOptional
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 invokegetData()
twice.
– Holger
yesterday
1
...or even Objects.requireNonNullElseGet
– Hulk
yesterday
|
show 3 more comments
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())
;
since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
– Mykyta Bezverkhyi
yesterday
1
Typouser.getDate()
, should beuser.getData()
... and @Eran I really doubt one should be usingOptional
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 invokegetData()
twice.
– Holger
yesterday
1
...or even Objects.requireNonNullElseGet
– Hulk
yesterday
|
show 3 more comments
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())
;
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())
;
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
Typouser.getDate()
, should beuser.getData()
... and @Eran I really doubt one should be usingOptional
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 invokegetData()
twice.
– Holger
yesterday
1
...or even Objects.requireNonNullElseGet
– Hulk
yesterday
|
show 3 more comments
since Collections.emptyMap() is a constant we can simply use orElse(emptyMap()), but thanks
– Mykyta Bezverkhyi
yesterday
1
Typouser.getDate()
, should beuser.getData()
... and @Eran I really doubt one should be usingOptional
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 invokegetData()
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
|
show 3 more comments
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>>
.
.filter(user -> user != null && ...)
– Andrew Tobilko
yesterday
@AndrewTobilko why? is auser
would benull
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
add a comment |
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>>
.
.filter(user -> user != null && ...)
– Andrew Tobilko
yesterday
@AndrewTobilko why? is auser
would benull
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
add a comment |
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>>
.
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>>
.
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 auser
would benull
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
add a comment |
.filter(user -> user != null && ...)
– Andrew Tobilko
yesterday
@AndrewTobilko why? is auser
would benull
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
add a comment |
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 aPredicate
,filter(Objects::nonNull)
I nominate this as the most readable thing here.
– candied_orange
4 hours ago
add a comment |
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 aPredicate
,filter(Objects::nonNull)
I nominate this as the most readable thing here.
– candied_orange
4 hours ago
add a comment |
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 aPredicate
,filter(Objects::nonNull)
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 aPredicate
,filter(Objects::nonNull)
answered 6 hours ago
Illya Kysil
684310
684310
I nominate this as the most readable thing here.
– candied_orange
4 hours ago
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited 4 hours ago
candied_orange
4,1271647
4,1271647
answered yesterday
Marv
2,56311131
2,56311131
add a comment |
add a comment |
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
If
user.getData()
returnsnull
, it should be wrapped to anOptional
to callorElse
.The stream's
findAny().orElse
operates on the stream's result itself. But what you need here is to check ifuser.getData()
exists. So you can not use stream's result'sorElse
directly.
add a comment |
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
If
user.getData()
returnsnull
, it should be wrapped to anOptional
to callorElse
.The stream's
findAny().orElse
operates on the stream's result itself. But what you need here is to check ifuser.getData()
exists. So you can not use stream's result'sorElse
directly.
add a comment |
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
If
user.getData()
returnsnull
, it should be wrapped to anOptional
to callorElse
.The stream's
findAny().orElse
operates on the stream's result itself. But what you need here is to check ifuser.getData()
exists. So you can not use stream's result'sorElse
directly.
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
If
user.getData()
returnsnull
, it should be wrapped to anOptional
to callorElse
.The stream's
findAny().orElse
operates on the stream's result itself. But what you need here is to check ifuser.getData()
exists. So you can not use stream's result'sorElse
directly.
edited 4 hours ago
candied_orange
4,1271647
4,1271647
answered yesterday
shawn
2,856616
2,856616
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
Maybe your
User::getData
should return aOptional<Map<K, V>>
then you can apply...map(user -> user.getData().orElseGet(this::emptyMap))....
.– Flown
yesterday
What's the
emptyMap
in the question what aregetData
andgetId
, 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 ofnull
. Returningnull
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 whatemptyMap
is or what is the eventual return type of your statement is!! I mean who knows if there is anOptional
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