在过滤器删除所有元素后处理元素



我有一个问题,我过滤了流的一些元素,过滤器可以删除一些或所有元素。如何处理过滤后没有元素留下的情况?

我试图检查是否有任何元素使用Optional<T>,这是一个合乎逻辑的事情,但即使在这里我得到了NullPointerException。下面是一个例子:

Optional<T> elem = details.stream()
.filter(T::test)
.findFirst(); //<=============== NPE
if(elem.isPreset){...}

如何处理?

就像Holger说的,NPE不可能来自对findFirst()的调用,除非null元素存在。简而言之:在应用过滤器方法之前过滤掉null元素,或者确保它是一个静态方法,并为null元素返回false

在任何情况下,这应该工作:

Optional<T> elem = details.stream()
.filter(Objects::nonNull)
.filter(T::test)
.findFirst();

可能原因

下面是异常

的可能性
  1. 过滤后的数据可能包含null
List<String> records = new ArrayList<>();
records.add(null);
Optional<String> opt = records.stream().filter(str -> str == null || str.length() > 5).findFirst();
  1. 请检查T::test是否允许null值,如果允许,请修复
  2. 即使null值可以在输入和其他过滤器中出现,也请在调用findFirst之前添加.filter(Objects::nonNull)

建议尝试使用非空过滤器

List<String> records = new ArrayList<>();
records.add(null);
Optional<String> opt = records.stream().filter(str -> str == null || str.length() > 5).filter(Objects::nonNull).findFirst();

从我所看到的,你的代码似乎很好。可选应该能够存储空值而不抛出异常。

然后下一行代码:

if(elem.isPreset){
/// your logic on elem goes here
}

应该防止NPE代码,因为如果elem为空,则条件应为假。

NPE可能来自这一行:

Optional<T> elem = details.stream()
.filter(T::test)//<=============== NPE
.findFirst(); 

所以我建议添加这个:

Optional<T> elem = details.stream()
.filter(Objects::nonNull)//<== this removes null elems
.filter(T::test)
.findFirst();