【问题标题】:Remove all Optional empty/null values from arraylist in java从java中的arraylist中删除所有可选的空/空值
【发布时间】:2018-12-16 04:52:27
【问题描述】:

我需要从List<Optional<String>> 中删除所有空/空值。

例子:

List<Optional<String>> list = new ArrayList<>();

list.add(Optional.empty());
list.add(Optional.of("Str1"));
list.add(Optional.of("Str2"));
list.add(Optional.of("Str3"));
list.add(Optional.of("Str4"));
list.add(Optional.of("Str5"));
list.add(Optional.empty());
list.add(Optional.ofNullable(null));

目前,我正在使用以下方法之一:

方式一:

List<String> collect = list.stream()
                   .filter(Optional::isPresent)
                   .map(obj ->obj.get())
                   .collect(Collectors.toList());

方式二:

List<Optional<String>> emptlist = new ArrayList<>();
emptlist.add(Optional.empty());
list.removeAll(emptlist);

还有其他更好的方法吗?

【问题讨论】:

  • 您是要创建列表的过滤副本并将可选项转换为字符串,还是要从列表中删除空元素?选项 1 是前者,选项 2 是后者。所以他们根本不做同样的事情。如果是后者,使用 removeIf() 会更清晰。
  • 到底是什么问题?但是使用Collection.removeIf。就像list.removeIf(o -&gt; !o.isPresent());
  • 您的编辑并没有真正帮助(我之前能够阅读),您仍然不清楚,首先您要求“List&lt;Optional&lt;String&gt;&gt;.中删除所有空/空值”然后您在 cmets 中说“-需要过滤列表的单独副本”。那么它是什么?请提供minimal reproducible example 解释您的期望。
  • Filtering a Stream of Optionals in Java。此外,IMO 第一种方法与使用 java-8 一样干净,尽管您可以使用 map(Optional::get) 而不是 map(obj -&gt;obj.get())

标签: java java-8 java-stream java-9


【解决方案1】:

使用 Java9,您可以使用新添加的 Optional::stream API 来做到这一点:

List<String> collect = list.stream()
               .flatMap(Optional::stream)
               .collect(Collectors.toList());

此方法可用于将可选元素的Stream 转换为 一个Stream的现值元素

坚持使用 Java8,问题中的 Way1 就足够了,恕我直言 -

List<String> collect = list.stream()
               .filter(Optional::isPresent)
               .map(Optional::get) // just a small update of using reference
               .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    removeIf 是最短的方法:

    list.removeIf(x -> !x.isPresent());
    

    【讨论】:

    • 仅当该列表支持删除时
    • @Eugene:OP 的第二个变体使用removeAll 暗示了这一点。但即使这样也可以简化为单个衬里:list.removeAll(List.of(Optional.empty()));
    【解决方案3】:

    对于希望获得一点乐趣或更好地了解 Optionals 和 Streams 工作的任何人(Java 8):

    List<String> collect=list.stream().
                                       map(z->z.map(Stream::of)).
                                       flatMap(ox->ox.orElseGet(Stream::empty)).
                                       collect(Collectors.toList());
    
    1. 第一个映射函数将 Optional[String] 转换为 Optional [流[字符串]]。流字符串[可选 [Stream[String]]] 因此被向前传递
    2. flatmap 的“map”部分将每个 Optional[Stream[String]] 转换为 Stream[String]。所有空的 Optional 都被空的 Stream 替换。现在我们有了 Stream[Stream[String]]。
    3. “平面”部分将 Stream[Stream[String]] 转换为 Stream[String]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多