Java streams可选,对两项进行空检查
我有下面的代码,它在两个值上工作,即。Java streams可选,对两项进行空检查,java,java-stream,optional,Java,Java Stream,Optional,我有下面的代码,它在两个值上工作,即。字符串的列表和字符串。列表和字符串都可以是null List<String> myStringList = getMyStringList(); // may return null String myString = "abc"; // may be null List<String> finalStringList = Optional.ofNullable(myStringList) .map(stri
字符串的列表
和字符串
。列表
和字符串
都可以是null
List<String> myStringList = getMyStringList(); // may return null
String myString = "abc"; // may be null
List<String> finalStringList = Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
List myStringList=getMyStringList();//可能返回null
字符串myString=“abc”//可能为空
List finalStringList=可选。不可用(myStringList)
.map(字符串->字符串.stream()
.filter(obj->StringUtils.isEmpty(myString)
||myString.equals(obj))
.collect(收集器.toList())
.orElseGet(ArrayList::new);
这个想法是:
如果myStringList
为null
,则会导致ArrayList
为空。
如果myString
为null
,则按原样返回myStringList
。
如果myString
不为空,则循环遍历列表并返回与myString
匹配的所有项目
问题是,使用上面的解决方案,即使myString
为空,我仍然循环遍历整个列表(strings.stream
)
假设myStringList
很大,当myString
为空时,如何避免循环列表
就是
1) 对列表执行空检查。如果为null,则返回一个新的空列表
2) 对myString
执行空检查。如果为null,则按原样返回列表,不循环
3) 如果myString
不为空,则循环遍历列表并返回筛选后的列表。您可以使用三元值,例如
List<String> finalStringList = myString == null ?
Collections.emptyList()
: Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
你可以用三元数,比如
List<String> finalStringList = myString == null ?
Collections.emptyList()
: Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
这可能适用于您(使用Java 9+):
List result2=Optional.ofNullable(myString)
.filter(对象::非空)
.map(mystr->Optional.ofNullable(myStringList)
.filter(对象::非空)
。或(()->可选。of(new ArrayList())
.stream()
.flatMap(列表::流)
.filter(mystr::equals)
.collect(Collectors.toList())//ArrayList不保证
.orElse(myStringList);
如果您使用的是Java 8,以下内容应该可以使用,但看起来有点难读:
List<String> result = Optional.ofNullable(myString)
.filter(Objects::nonNull)
.map(mystr -> Optional.ofNullable(myStringList)
.filter(Objects::nonNull)
.map(list -> list.stream()
.filter(mystr::equals)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new))
.orElse(myStringList);
List result=Optional.ofNullable(myString)
.filter(对象::非空)
.map(mystr->Optional.ofNullable(myStringList)
.filter(对象::非空)
.map(list->list.stream()
.filter(mystr::equals)
.collect(收集器.toList())
.OrelGet(ArrayList::new))
.orElse(myStringList);
这可能适用于您(使用Java 9+):
List result2=Optional.ofNullable(myString)
.filter(对象::非空)
.map(mystr->Optional.ofNullable(myStringList)
.filter(对象::非空)
。或(()->可选。of(new ArrayList())
.stream()
.flatMap(列表::流)
.filter(mystr::equals)
.collect(Collectors.toList())//ArrayList不保证
.orElse(myStringList);
如果您使用的是Java 8,以下内容应该可以使用,但看起来有点难读:
List<String> result = Optional.ofNullable(myString)
.filter(Objects::nonNull)
.map(mystr -> Optional.ofNullable(myStringList)
.filter(Objects::nonNull)
.map(list -> list.stream()
.filter(mystr::equals)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new))
.orElse(myStringList);
List result=Optional.ofNullable(myString)
.filter(对象::非空)
.map(mystr->Optional.ofNullable(myStringList)
.filter(对象::非空)
.map(list->list.stream()
.filter(mystr::equals)
.collect(收集器.toList())
.OrelGet(ArrayList::new))
.orElse(myStringList);
其他解决方案
List myStringList=Arrays.asList(“abc”、“aef”);//可能返回null
字符串myString=“abc”//可能为空
映射谓词Map=Map.of(
(v) ->myStringList==null,()->new ArrayList(),//对列表进行null检查。如果为null,则返回一个新的空列表。
(v) ->myString==null,()->myStringList,//对myString执行null检查。如果为null,则按原样返回列表,而不进行循环。
(v) ->true,()->myStringList.stream()//如果myString不为null,则循环遍历列表并返回筛选后的列表。
.filter(myString::equals)
.collect(收集器.toList())
);
List outputList=predicateMap.entrySet().stream()
.filter(p->p.getKey().test(null))
.findFirst().get().getValue().get();
System.out.println(输出列表);
其他解决方案
List myStringList=Arrays.asList(“abc”、“aef”);//可能返回null
字符串myString=“abc”//可能为空
映射谓词Map=Map.of(
(v) ->myStringList==null,()->new ArrayList(),//对列表进行null检查。如果为null,则返回一个新的空列表。
(v) ->myString==null,()->myStringList,//对myString执行null检查。如果为null,则按原样返回列表,而不进行循环。
(v) ->true,()->myStringList.stream()//如果myString不为null,则循环遍历列表并返回筛选后的列表。
.filter(myString::equals)
.collect(收集器.toList())
);
List outputList=predicateMap.entrySet().stream()
.filter(p->p.getKey().test(null))
.findFirst().get().getValue().get();
System.out.println(输出列表);
我个人认为,if else
编写的代码可读性/可维护性/效率更高:
if (myStringList == null || myStringList.size() == 0) {
return Collections.emptyList();
} else if (StringUtils.isEmpty(myString)) {
return new ArrayList<>(myStringList); // or return myStringList;
} else {
return myStringList.stream().filter(e -> myString.equals(e))
.collect(Collectors.toList());
}
我个人认为,if else
编写的代码将更具可读性/可维护性/效率:
if (myStringList == null || myStringList.size() == 0) {
return Collections.emptyList();
} else if (StringUtils.isEmpty(myString)) {
return new ArrayList<>(myStringList); // or return myStringList;
} else {
return myStringList.stream().filter(e -> myString.equals(e))
.collect(Collectors.toList());
}
为什么不使用简单的if检查。最佳解决方案:修复getMyStringList()
以返回空列表,而不是null
。相关且非常好的阅读:(我建议此问题部分重复该问题)@Vicky如果你能用myString
和myStringList
的存在和不存在的所有4种可能的组合得出期望值,那么问题就非常清楚了。wh