合并List <T>和List <Optional <T >>

Emi*_*tis 2 java java-8 java-stream

鉴于:

    List<Integer> integers = new ArrayList<>(Arrays.asList(
            10, 12
    ));

    List<Optional<Integer>> optionalIntegers = Arrays.asList(
            Optional.of(5),
            Optional.empty(),
            Optional.of(3),
            Optional.of(2),
            Optional.empty()
    );

    List<Integer> unwrappedOptionals = optionalIntegers.stream()
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(Collectors.toList());

    integers.addAll(unwrappedOptionals);
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来展开Optionals,或者将它们合并到一起的其他方式List<Integer>?List在做之前将它们收集到新的中感觉非常浪费addAll().

Era*_*ran 5

如果你不希望创建一个中间List直接加入过滤元件,以原来的integers List使用forEach(),而不是collect():

optionalIntegers.stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .forEach(integers::add);
Run Code Online (Sandbox Code Playgroud)

或者,正如Sergey Lagutin建议的那样,你可以使用Optional's map()和orElse()方法flatMap():

optionalIntegers.stream()
                .flatMap(o -> o.map(Stream::of)
                               .orElse(Stream.empty()))
                .forEach(integers::add);
Run Code Online (Sandbox Code Playgroud)


Tag*_*eev 5

使用新的Java-9 Optional.stream()方法,可以这样编写:

optionalIntegers.stream()
                .flatMap(Optional::stream)
                .forEach(integers::add);
Run Code Online (Sandbox Code Playgroud)

在Java-9之前,您可以将此类方法添加到您自己的实用程序类中:

public class StreamUtil {
    public static <T> Stream<T> fromOptional(Optional<T> opt) {
        return opt.isEmpty() ? Stream.empty() : Stream.of(opt.get());
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

optionalIntegers.stream()
                .flatMap(StreamUtil::fromOptional)
                .forEach(integers::add);
Run Code Online (Sandbox Code Playgroud)