java lambda-如何遍历可选列表/可选流

时间:2018-08-03 08:21:15

标签: java lambda java-8 java-stream optional

具有Optional的可选列表,例如:

Optional<List<Optional<String>>> optionalList = Optional.of(
    Arrays.asList(
        Optional.empty(),
        Optional.of("ONE"),
        Optional.of("TWO")));

如何遍历optionalList以打印出字符串的ONETWO

拥有可选的可选流怎么样?

Optional<Stream<Optional<String>>> optionalStream = Optional.of(
    Stream.of(
        Optional.empty(),
        Optional.of("ONE"),
        Optional.of("TWO")));

更新:感谢您的回答,以及optionalStream(非嵌套)的解决方案:

optionalStream
    .orElseGet(Stream::empty)
    .filter(Optional::isPresent)
    .map(Optional::get)
    .forEach(System.out::println);

6 个答案:

答案 0 :(得分:4)

首先,检查Optional是否存在。如果是,则流式处理列表并过滤非空列表,然后打印每个列表。

optionalList.ifPresent(list -> list.stream()
            .filter(Optional::isPresent)
            .map(Optional::get)
            .forEach(System.out::println));

对于流情况也差不多

optionalStream.ifPresent(stream -> stream
            .filter(Optional::isPresent)
            .map(Optional::get)
            .forEach(System.out::println));

答案 1 :(得分:3)

您确实可以流Option<String>并仅过滤非空值。

Optional<List<Optional<String>>> optionalList = Optional.of(Arrays.asList(Optional.empty(), Optional.of("ONE"), Optional.of("TWO")));

optionalList.orElseGet(ArrayList::new)
            .stream()
            .filter(Optional::isPresent)
            .map(Optional::get)           
            .forEach(System.out::println);

您还可以按照其他答案中的建议使用Optional.ifPresent()

optionalList.ifPresent(l -> l.stream()
                             .filter(Optional::isPresent)
                             .map(Optional::get)                               
                             .forEach(System.out::println));

我个人更喜欢第一种方法,因为它消除了嵌套的层次:我觉得阅读起来更愉快。

答案 2 :(得分:2)

我看到有两种方法,第二种对我来说看起来更漂亮,看看:

class Scratch {
    public static void main(String[] args) {
        Optional<String> element1 = Optional.of("test1");
        Optional<String> element2 = Optional.empty();
        Optional<String> element3 = Optional.of("test2");
        Optional<String> element4 = Optional.of("test3");
        List<Optional<String>> list = Arrays.asList(element1, element2, element3, element4);

        System.out.println(extractStrings1(list));
        System.out.println(extractStrings2(list));
    }

    private static List<String> extractStrings1(List<Optional<String>> list) {
        return list.stream()
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());
    }

    private static List<String> extractStrings2(List<Optional<String>> list) {
        List<String> result = new ArrayList<>();
        list.forEach(element -> element.ifPresent(result::add));
        return result;
    }
}

答案 3 :(得分:1)

好吧...

  1. 检查是否存在可选列表。
  2. 对(现在存在的)列表的所有元素进行“每个”。
  3. 在每个步骤中,检查是否存在可选字符串。
  4. 如果是,请打印出来。

单线可以做到这一点:

optionalList.ifPresent(list -> list.forEach(s -> s.ifPresent(System.out::println)));

答案 4 :(得分:1)

如果您可以使用Java 9,可以这样做:

.stream()

对于可选流来说,它是相同的,没有第一个Optional::stream调用。

对于Java 8,您没有可用的optionalList.ifPresent(list -> list.stream() .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty)) .forEach(System.out::println)); 方法,因此您可以自己进行操作:

Stream

对于Optional中的optionalStream.ifPresent(stream -> stream .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty)) .forEach(System.out::println)); ,看起来像这样:

<API-MAPPINGS>

答案 5 :(得分:0)

optionalList.stream().flatMap(List::stream).filter(Objects::nonNull).forEach(...)