使用Java Stream API进行分层过滤

伍德查克

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

具体来说,我要根据特定的过滤条件将此地图过滤到列表中。

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保留分层条件检查的惯用方法是什么?

霍尔格

在a之后链接的操作filter仅对谓词接受的元素执行。因此,无需为此担心。

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

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

除此之外,与循环相比,您还进行了其他不必要的更改。该循环迭代values(),而你使用的地图视图entrySet()的流代替,引入需要调用getValue()Map.Entry四次。

循环逻辑的直接转换要简单得多:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章