如何使用可选列表的每个元素?

时间:2016-07-29 05:19:15

标签: java lambda java-stream

我有一个可以为null的List;

List<T> list; // may or may not null

我想为消费者处理每个元素。

到目前为止,我做到了。

ofNullable(list)
        .map(List::stream)
        .ifPresent(stream -> stream.forEach(e -> {}));

ofNullable(eventDataList).ifPresent(v -> v.forEach(e -> {}));

有没有简单或简洁的方法来做到这一点?

4 个答案:

答案 0 :(得分:3)

从技术上讲,if (list != null) { list.stream().forEach(e -> {...}); }在CPU /内存使用方面比变体更短,效率更高。

从架构上讲,如果您可以控制list的初始化及其用法,那么使用Collections.emptyList()代替null通常会更好(如果你的逻辑是程序允许)或从一开始就制作列表Optional。这样可以避免在每次要使用列表时进行检查或创建Optional的必要性。

答案 1 :(得分:2)

如果您需要对列表中的每个值进行操作并说返回一个值,那么ifPresent将不起作用。相反,您可以执行以下操作。在我的示例中,可选列表包含用户定义的对象Person,该对象具有一些属性。我正在遍历列表,并连接特定属性的值并返回它。

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);
    }

答案 2 :(得分:1)

我不确定你能否使它更简洁。但是,如果您经常使用循环遍历可空列表并使用每个元素的构造,那么您可以创建一个小类来实现这一点:

public class ListConsumer {
    public static <H> Consumer<List<H>> of(Consumer<H> consumer) {
        return hs -> hs.forEach(consumer);
    }
}

然后,您可以按如下方式使用列表中的每个元素(例如,在列表中打印所有字符串):

List<String> list = Arrays.asList("A", "B", "C");

Consumer<String> consumer = System.out::println;
Optional.ofNullable(list).ifPresent(ListConsumer.of(consumer));

答案 3 :(得分:1)

为避免丑陋的null检查,请使用orElse(Collections.emptyList())

Optional.ofNullable(eventDataList)
        .orElse(Collections.emptyList())
        .forEach(e -> {});

使用静态导入,非常简洁:

ofNullable(eventDataList).orElse(emptyList()).forEach(e -> {});