在Java中从ArrayList中删除所有可选的空/ null值

18
需要从 List<Optional<String>> 中移除所有的空值/ null 值。
示例:
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));

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

方法1:

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);

还有其他更好的方法吗?


3
你想要创建一个带过滤的列表副本并将可选项转换为字符串,还是删除列表中的空元素?选项1执行前者,选项2执行后者。因此它们完全不同。如果选择后者,则使用removeIf()会更清晰。 - JB Nizet
3
确切的问题是什么?但使用Collection.removeIf。可以像这样简单地写:list.removeIf(o -> !o.isPresent()); - AxelH
2
你的编辑并没有真正帮助到我(我之前就能读懂),你仍然不够清晰。首先,你要求“从List<Optional<String>>中删除所有空/ null值”,然后在评论中又说“需要过滤后的列表的单独副本”。那么这是什么意思?请提供一个[mcve],解释你的期望。 - AxelH
2
请参阅[Filtering a Stream of Optionals in Java](http://www.baeldung.com/java-filter-stream-of-optional)。我认为,第一种方法是使用Java-8编写最干净的方法,尽管您可以使用“map(Optional :: get)”而不是“map(obj-> obj.get())”。 - Ousmane D.
3个回答

22

使用新添加的Optional::stream API,您可以使用Java9实现此操作:


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

这种方法可以用于将一个Optional元素的流转换为一个present value元素的流

坚持使用Java8,问题中的Way1在我看来已经足够好了 -

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

8

removeIf 是最简单的方法:

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

8
仅当该列表支持删除时。 - Eugene
1
@Eugene:这是由OP的第二个变体使用removeAll所暗示的。但即使如此,它也可以简化为一行代码:list.removeAll(List.of(Optional.empty())); - Holger

0

对于任何想要玩一下或更好地理解可选项和流的工作方式的人(Java 8):

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接