web-dev-qa-db-ja.com

java lambda-オプションリスト/オプションのストリームをトラバースする方法

次のようなオプションのオプションリストがあります:

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

optionalListをトラバースして文字列のONEおよびTWOを出力する方法

オプションのオプションのストリームを持つことはどうですか?

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);
5
Sara Vino

まず、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));
5
user7

Java 9を使用できる場合は、次のように実行できます。

_optionalList.ifPresent(list -> list.stream()
  .flatMap(Optional::stream)
  .forEach(System.out::println));
_

オプションのストリームの場合、最初の.stream()呼び出しがなければ同じです。

Java 8を使用すると、_Optional::stream_メソッドを使用できないため、自分で実行できます。

_optionalList.ifPresent(list -> list.stream()
  .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty))
  .forEach(System.out::println));
_

そして、Stream of Optionalsの場合、次のようになります。

_optionalStream.ifPresent(stream -> stream
  .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty))
  .forEach(System.out::println));
_
4
jbx

実際に_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));
_

個人的には、ネストされたレベルを削除するため、最初の方法を好みます。読む方が楽しいと思います。

3
davidxxx

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;
    }
}
2
rastaman

上手 ...

  1. オプションのリストが存在するかどうかを確認します。
  2. (現在の)リストのすべての要素に対して「for each」を実行します。
  3. 各ステップで、オプションの文字列が存在するかどうかを確認します。
  4. はいの場合は、印刷します。

ワンライナーはそれを行うことができます:

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