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