There is a list of elements of the Event class.
@Data
@AllArgsConstructor
public class Event {
private Long id;
private String nameRu;
private String nameEn;
}
I want to get value of one field from an Event (any of the objects).
Event event1 = new Event(1, null, null);
Event event2 = new Event(2, null, null);
List<Event> events = new ArrayList<>();
events.add(event1);
events.add(event2);
int languageId = 1;
String name = events.stream().map(s -> {
if (languageId == 1)
return s.getNameEn();
else if (languageId == 2)
return s.getNameRu();
else return s.getNameEn();
}).findAny().orElse(null);
But if in each element this field has the value null, then stream.map() returns null (but it should return a stream of some number of nulls), and the findAny() call throws a NullPointerException.
Two questions:
According to JavaDoc this is expected behavior:
/**
* Returns an {@link Optional} describing some element of the stream, or an
* empty {@code Optional} if the stream is empty.
*
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>.
*
* <p>The behavior of this operation is explicitly nondeterministic; it is
* free to select any element in the stream. This is to allow for maximal
* performance in parallel operations; the cost is that multiple invocations
* on the same source may not return the same result. (If a stable result
* is desired, use {@link #findFirst()} instead.)
*
* @return an {@code Optional} describing some element of this stream, or an
* empty {@code Optional} if the stream is empty
* @throws NullPointerException if the element selected is null
* @see #findFirst()
*/
Optional<T> findAny();
@throws NullPointerException if the element selected is null
To fix this you must filter off null elements like this:
.map(s -> ... )
.filter(Objects::nonNull)
.findAny()
.orElse(null);