给定这个对象:
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
尝试返回值时会出错。
我错过了什么,或者有不同的方法来解决这个问题吗?
我认为可以更简单。
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());
}
这是一个递归解决方案,复制而不是修改值。 它也不使用扁平流方法。
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;
}