Reputation: 21978
I have a List which can be null;
List<T> list; // may or may not null
I want to process for each element with a consumer.
So far, I do.
ofNullable(list)
.map(List::stream)
.ifPresent(stream -> stream.forEach(e -> {}));
or
ofNullable(eventDataList).ifPresent(v -> v.forEach(e -> {}));
Is there any easy or concise way to do this?
Upvotes: 5
Views: 24273
Reputation: 631
If you require to do something with every value in the list and say return a value then ifPresent
will not work. Rather you can do something like below. In my example the optional list contains a user defined object Person
which has a few attributes. I am iterating over the list and concatenating the values of a specific attribute and returning it.
public static class Person
{
String name;
int age;
public Person(final String name, final int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public static void main(String[] args)
{
Person a = new Person("Alice", 1);
Person b = new Person("Bob", 2);
List<Person> personList = Lists.newArrayList(a, b);
String concatNames = Optional.of(personList).map(people -> people.stream().map(Person::getName).collect(Collectors.joining(" "))).orElse(null);
System.out.println("Names: "+concatNames);
}
Upvotes: 2
Reputation: 5926
To avoid ugly null checking, use orElse(Collections.emptyList())
Optional.ofNullable(eventDataList)
.orElse(Collections.emptyList())
.forEach(e -> {});
With static imports, it's pretty concise:
ofNullable(eventDataList).orElse(emptyList()).forEach(e -> {});
Upvotes: 7
Reputation: 6197
Technically, if (list != null) { list.stream().forEach(e -> {...}); }
is both shorter and more efficient in terms of CPU/memory usage than your variants.
Architecturally, if you have control over initialization of the list
and its usage, it's often better to use either Collections.emptyList()
instead of null
(if the logic of your program allows) or make the list Optional
from the very beginning. That would save you from necessity to make checks or create Optional
s every time you want to use the list.
Upvotes: 4
Reputation: 4380
I'm not sure that you can make it more concise. However, if you are frequently using the construct of looping over a nullable list and consuming each element, you could make a small class which does just that:
public class ListConsumer {
public static <H> Consumer<List<H>> of(Consumer<H> consumer) {
return hs -> hs.forEach(consumer);
}
}
You can then consume each element in a list as follows (e.g. print all Strings in list):
List<String> list = Arrays.asList("A", "B", "C");
Consumer<String> consumer = System.out::println;
Optional.ofNullable(list).ifPresent(ListConsumer.of(consumer));
Upvotes: 1