首页 > 解决方案 > 嵌套重复流过滤

问题描述

我正在学习 Java 流,并且有一种情况我需要在流上使用不同的过滤器,以防使用第一个过滤器进行过滤没有返回任何结果。目前我有这个,考虑是否有更好的方法来写这个:

String str = requestParams.entrySet()
        .stream()
        .filter(e -> e.getKey().contains("string1") && e.getValue().length() > 0)
        .map(Map.Entry::getValue)
        .findFirst().orElseGet(() -> requestParams.entrySet()
                .stream()
                .filter(e -> e.getKey().contains("string2") && e.getValue().length() > 0)
                .map(Map.Entry::getValue)
                .findFirst().orElse(""));

标签: javajava-stream

解决方案


因为您想在整个来源中搜索此条件e.getKey().contains("string1") && e.getValue().length() > 0,并且只有在不满足时才想进行另一次搜索,e.getKey().contains("string2") && e.getValue().length() > 0我会说您当前的方法很好,但只需将逻辑封装到一个方法中,这样您就可以干燥,即

static Optional<String> getValueByX(Map<String, String> requestParams, String searchString) {
       return requestParams.entrySet()
                .stream()
                .filter(e -> e.getKey().contains(searchString) && 
                             e.getValue().length() > 0)
                .map(Map.Entry::getValue)
                .findFirst();
}

然后你会称它为:

String result = getValueByX(requestParams, "string1")
                .orElseGet(() -> getValueByX(requestParams, "string2").orElse(""));

但是,如果您不关心在应用“string2”的条件之前在整个源中搜索“string1”,那么您最好这样做:

String str = requestParams.entrySet()
        .stream()
        .filter(e -> (e.getKey().contains("string1") || e.getKey().contains("string2")) && e.getValue().length() > 0)
        .map(Map.Entry::getValue)
        .findFirst().orElse("")

如果可能有比上述两个更多的选项,那么我将创建一个包含这些值的列表,然后执行:

List<String> search = Arrays.asList("string1", "string2"..........);
String result = requestParams.entrySet()
             .stream()
             .filter(e -> search.stream().anyMatch(a -> e.getKey().contains(a)) &&
                             e.getValue().length() > 0)
             .map(Map.Entry::getValue)
             .findFirst().orElse("");

推荐阅读