如何最好地从可为空对象创建 Java 8 流?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29406286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to best create a Java 8 stream from a nullable object?
提问by checketts
What is the best/idiomatic way of doing a null check before getting a stream?
在获取流之前进行空检查的最佳/惯用方法是什么?
I have method that is receiving a List
that might be null. So I can't just call .stream()
on the passed in value. Is there some static helper in that would give me an empty stream if a value is null?
我有接收List
可能为空的方法的方法。所以我不能只调用.stream()
传入的值。如果值为空,是否有一些静态助手会给我一个空流?
采纳答案by gdejohn
I agree with Stuart Marksthat list == null ? Stream.empty() : list.stream()
is the right way to do this (see his answer), or at least the right way to do this pre-Java 9 (see edit below), but I'll leave this answer up to demonstrate usage of the Optional API.
我同意Stuart Marks,这list == null ? Stream.empty() : list.stream()
是正确的方法(请参阅他的答案),或者至少是在 Java 9 之前执行此操作的正确方法(请参阅下面的编辑),但我将保留此答案以演示使用可选 API。
<T> Stream<T> getStream(List<T> list) {
return Optional.ofNullable(list).map(List::stream).orElseGet(Stream::empty);
}
Edit:Java 9 added the static factory method Stream.<T>ofNullable(T)
, which returns the empty stream given a null
argument, otherwise a stream with the argument as its only element. If the argument is a collection, we can then flatMap
to turn it into a stream.
编辑:Java 9 添加了静态工厂方法Stream.<T>ofNullable(T)
,它返回给定null
参数的空流,否则返回以该参数作为唯一元素的流。如果参数是一个集合,我们就可以flatMap
把它变成一个流。
<T> Stream<T> fromNullableCollection(Collection<? extends T> collection) {
return Stream.ofNullable(collection).flatMap(Collection::stream);
}
This doesn't misuse the Optional API as discussed by Stuart Marks, and in contrast to the ternary operator solution, there's no opportunity for a null pointer exception (like if you weren't paying attention and screwed up the order of the operands). It also works with an upper-bounded wildcard without needing SuppressWarnings("unchecked")
thanks to the signature of flatMap
, so you can get a Stream<T>
from a collection of elements of any subtype of T
.
这不会像 Stuart Marks 所讨论的那样滥用 Optional API,并且与三元运算符解决方案相比,没有机会出现空指针异常(就像您没有注意并搞砸了操作数的顺序)。SuppressWarnings("unchecked")
由于 的签名,它还可以与上限通配符一起使用flatMap
,因此您可以Stream<T>
从 的任何子类型的元素集合中获取T
。
回答by checketts
The best thing I can think of would be to use an Optional
with the orElseGet
method.
我能想到的最好的事情是使用Optional
withorElseGet
方法。
return Optional.ofNullable(userList)
.orElseGet(Collections::emptyList)
.stream()
.map(user -> user.getName())
.collect(toList());
Updatedwith @Misha's suggest to use Collections::emptyList
over ArrayList::new
更新@Misha 建议使用Collections::emptyList
overArrayList::new
回答by Stuart Marks
In the other answers, the Optional
instance is created and used strictly within the same statement. The Optional
class is primarily useful for communicating with the callerabout presence or absence of a return value, fused with the actual value if present. Using it wholly within a single method seems unnecessary.
在其他答案中,该Optional
实例是严格在同一语句中创建和使用的。的Optional
类是主要有用与呼叫者通信约一个返回值的存在或不存在,以及如果存在的实际值熔合。在单一方法中完全使用它似乎没有必要。
Let me propose the following more prosaic technique:
让我提出以下更平淡的技巧:
static <T> Stream<T> nullableListToStream(List<T> list) {
return list == null ? Stream.empty() : list.stream();
}
I guess the ternary operator is somewhat déclassé these days, but I think this is the simplest and most efficient of the solutions.
我猜现在三元运算符有点过时了,但我认为这是最简单和最有效的解决方案。
If I were writing this for real (that is, for a real library, not just sample code on Stack Overflow) I'd put in wildcards so that that the stream return type can vary from the List type. Oh, and it can be a Collection, since that's where the stream()
method is defined:
如果我是真实写的(也就是说,对于一个真正的库,而不仅仅是 Stack Overflow 上的示例代码),我会放入通配符,以便流返回类型可以与 List 类型不同。哦,它可以是一个集合,因为这stream()
是定义方法的地方:
@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll) {
return coll == null ? Stream.empty() : (Stream<T>)coll.stream();
}
(The warning suppression is necessary because of the cast from Stream<? extends T>
to Stream<T>
which is safe, but the compiler doesn't know that.)
(警告抑制是必要的,因为从Stream<? extends T>
to的强制转换Stream<T>
是安全的,但编译器不知道。)
回答by piotrek
apache commons-collections4:
apache commons-collections4:
CollectionUtils.emptyIfNull(list).stream()
回答by JustifiedAndAncient
Personally I consider null deprecated and use Optional wherever possible despite the (tiny) performance overhead. So I use the interface from Stuart Marks with an implementation based on gdejohn, i.e.
我个人认为 null 已弃用并尽可能使用 Optional 尽管(微小的)性能开销。所以我使用 Stuart Marks 的接口和基于 gdejohn 的实现,即
@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll)
{
return (Stream<T>) Optional.ofNullable(coll)
.map(Collection::stream)
.orElseGet(Stream::empty);
}