繁体   English   中英

分层过滤使用 Java Stream API

[英]Layered filtering using Java Stream API

我有一些命令式 Java 条件代码,我想重构以使用 Streams。

具体来说,我有这个 map,我想根据特定的过滤条件过滤到一个列表中。

private  Map<Integer,Thing> thingMap = new HashMap<Integer,Thing>();
// populate thingMap

这是使用它的代码:

List<Thing> things = new ArrayList<Thing>();

for (Thing thing : thingMap.values()) {
    if (thing.getCategory().equals(category)) {
        if (location == null) {
            things.add(thing);
        } else if (thing.getLocation().equals(location)) {
            things.add(thing);
        }
    }
}

我将其重构为以下内容。 但是缺少的是我希望在类别过滤器通过时才检查位置。 另外,我怀疑有更好的方法来做到这一点:

List<Thing> things = thingMap.entrySet()
                      .stream()
                      .filter(t -> t.getValue().getCategory().equals(category))
                      .filter(t -> 
                          location == null || 
                          t.getValue().getLocation().equals(location)
                       )
                      .map(Map.Entry::getValue)
                      .collect(Collectors.toList());
    

使用 Streams 保留分层条件检查的惯用方法是什么?

filter之后链接的操作只会对谓词接受的元素执行。 所以没有必要担心这一点。

您还可以将条件加入单个filter步骤,就像您可以将嵌套的if语句加入单个if一样,通过使用&&组合条件。 结果是一样的。

但请注意,循环使用条件location == null ,指的是在您发布的代码片段之外声明的变量,而不是thing.getLocation() == null

除此之外,与循环相比,您还进行了其他不必要的更改。 该循环遍历 map 的values()视图,而您将entrySet()用于 Stream,从而需要在Map.Entry上调用getValue()四次。

循环逻辑的直接翻译要简单得多:

List<Thing> things = thingMap.values().stream()
    .filter(thing -> thing.getCategory().equals(category))
    .filter(thing -> location == null || thing.getLocation().equals(location))
    .collect(Collectors.toList());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM