使用递归子级列表递归过滤对象

问题描述 投票:0回答:2

给定这个对象:

public class Menu {

  private String id;
  private String matchCode;
  private List<Menu> children;
  
  //getters and setters

  /**
   * Flattened funcition to recursive children list
   */
  public Stream<Menu> flatenned() {
    return Stream.concat(
          Stream.of(this),
          children.stream().flatMap(Menu::flatenned));
  }

}

我需要过滤

List<Menu>
并删除与给定
matchCode
不匹配的所有(父)项目。我还需要通过同一字段过滤所有子项(此时可以有“N”个子项)(
matchCode
)。

由于孩子们是一个递归列表结构,我发现方法

flatenned
可以帮助实现这一点。 (请参阅Konrad Garus:使用 Java 8 流遍历递归数据结构)。

到目前为止我有这个:

private List<Menu> filterByMatchRoleCode(List<Menu> menuList) {
  return menuList.stream()
    .filter(p -> "string".matches(p.getMatchCode()))
    .map(c -> c.getChildren()
          .stream()
          .map(o -> o.flatenned()
                .map(Menu::getMatchCode)
                .filter(v -> "string".matches(v)).collect(Collectors.toList())));
}

此方法

filterByMatchRoleCode
尝试返回值时会出错。

我错过了什么,或者有不同的方法来解决这个问题吗?

java list java-stream recursive-datastructures
2个回答
1
投票

我认为可以更简单。

    private List<Menu> filterByMatchRoleCode(List<Menu> menuList) {
        return menuList.stream()
                .peek( x -> x.setChildren( filterByMatchRoleCode(x.children)))
                .filter(p -> "string".matches(p.getMatchCode()))
                .collect(Collectors.toList());
    }

0
投票

这是一个递归解决方案,复制而不是修改值。 它也不使用扁平流方法。

List<Menu> filterByMatchRoleCode(List<Menu> menuList) {
    return menuList.stream()
            .filter(m -> "string".matches(m.getMatchCode()))
            .map(this::copyWithFilteredChildren)
            .toList();
}

private Menu copyWithFilteredChildren(Menu menu) {
    Menu filtered = new Menu();
    filtered.setId(menu.getId());
    filtered.setMatchCode(menu.getMatchCode());
    filtered.setChildren(filterByMatchRoleCode(menu.getChildren()));
    return filtered;
}
© www.soinside.com 2019 - 2024. All rights reserved.