Java流可选,对两项进行空检查

我有以下代码适用于两个值,即。 List中的StringString中的一个。 ListString都可以是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);

想法是: 如果myStringListnull,则结果为空ArrayList。 如果myStringnull,则照原样返回myStringList。 如果myString不为null,则遍历该列表并返回与myString匹配的所有项目。

问题是,使用上述解决方案,即使strings.stream为空,我仍会遍历整个列表(myString)。

假设myStringList很大,如何避免在myString为null的情况下循环列表?

也就是说,

1)对列表进行空检查。如果为null,则返回一个新的空列表。

2)对myString进行空检查。如果为null,则按原样返回该列表。

3)如果myString不为null,则循环浏览列表并返回过滤后的列表。

southwesting1228 回答:Java流可选,对两项进行空检查

您可以使用三元类,

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

或基本的if,默认为空列表。喜欢,

List<String> finalStringList = Collections.emptyList();
if (myString != null) {
    finalStringList = Optional.ofNullable(myStringList)
            .map(strings -> strings.stream()
                    .filter(obj -> StringUtils.isEmpty(myString)
                            || myString.equals(obj))
                    .collect(Collectors.toList()))
            .orElseGet(ArrayList::new);
}
,

这可能对您有用(对于Java 9 +):

List<String> result2 = Optional.ofNullable(myString)
  .filter(Objects::nonNull)
  .map(mystr -> Optional.ofNullable(myStringList)
                        .filter(Objects::nonNull)
                        .or(() -> Optional.of(new ArrayList<>()))
                        .stream()
                        .flatMap(List::stream)
                        .filter(mystr::equals)
                        .collect(Collectors.toList())) //ArrayList not guaranteed
    .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<String> myStringList = Arrays.asList("abc","aef"); // may return null
String myString = "abc"; // may be null

Map<Predicate,Supplier<List<String>>> predicateMap = Map.of(
      (v) -> myStringList == null,() -> new ArrayList<>(),// do a null check on the list. If null,return a new empty list.
      (v) -> myString == null,() -> myStringList,// do a null check on myString. If null,return the list as is WITHOUT LOOPING.
      (v) -> true,() -> myStringList.stream() // if myString is not null,loop through the list and return the filtered list.
                .filter(myString::equals)
                .collect(Collectors.toList())
      );
List<String> outputList = predicateMap.entrySet().stream()
      .filter(p -> p.getKey().test(null))
      .findFirst().get().getValue().get();

System.out.println(outputList);
,

我个人认为,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());
}

好的,如果您真的想避免编写几行代码,请尝试使用我的库:abacus-util

return N.isNullOrEmpty(myString) ? N.newArrayList(myStringList) 
                                 : N.filter(myStringList,e -> myString.equals(e));
本文链接:https://www.f2er.com/3154863.html

大家都在问