Guava:将List <Optional <T >>转换为List <T>,只保留当前值

Kkk*_*kev 5 java guava

有没有一种优雅的方式使用Guava从选项列表转换为现值列表?

例如,从

ImmutableList.of(
    Optional.of("Tom"), Optional.<String>absent(), Optional.of("Dick"),
    Optional.of("Harry"), Optional.<String>absent()
)
Run Code Online (Sandbox Code Playgroud)

到一个只包含的列表

["Tom", "Dick", "Harry"]
Run Code Online (Sandbox Code Playgroud)

一种方法是:

List<T> filterPresent(List<Optional<T>> inputs) {
    return FluentIterable.from(inputs)
            .filter(new Predicate<Optional<T>>() {
                @Override
                public boolean apply(Optional<T> optional) {
                    return optional.isPresent();
                }
            }).transform(new Function<Optional<T>, T>() {
                @Override
                public T apply(Optional<T> optional) {
                    return optional.get();
                }
            }).toList();
}
Run Code Online (Sandbox Code Playgroud)

但这很冗长.

遗憾的是,Java 8不是一个选项.

Xae*_*ess 15

在Guava中有实际的内置方法:presentInstancesinOptional:

从提供的选项中返回每个当前实例的值,按顺序跳过absent().迭代器是不可修改的并且被懒惰地评估.

例:

List<Optional<String>> optionalNames = ImmutableList.of(
    Optional.of("Tom"), Optional.<String>absent(), Optional.of("Dick"),
    Optional.of("Harry"), Optional.<String>absent());

Iterable<String> presentNames = Optional.presentInstances(optionalNames); // lazy

// copy to List if needed
List<String> presentNamesList = ImmutableList.copyOf(presentNames);
System.out.println(presentNamesList); // ["Tom", "Dick", "Harry"]
Run Code Online (Sandbox Code Playgroud)


Kon*_*kov 5

为什么不用老式的Java方式呢:

List<T> result = new ArrayList<T>();
for (Optional<T> optional : inputs) {
    if (optional.isPresent()) {
        result.add(optional.get());
    }
}
return result;
Run Code Online (Sandbox Code Playgroud)