如何用Java 8 Stream压缩嵌套的列表映射?
作者:互联网
参见英文答案 > In Java, how do I efficiently and elegantly stream a tree node’s descendants? 4个
我有一个看起来像这样的结构:
public class Category {
private String tag;
private String name;
private String description;
private List<Item> items;
}
和Item看起来像这样
public class Item {
private String itemTag;
private String itemName;
private String itemType;
private Integer itemStatus;
private List<Item> items;
}
这不是最好的设计 – 我知道,但我无权改变这种设计.
我正在尝试找到一种方法将此结构展平为单个Stream并找到具有匹配itemTag的Item.使用此代码:
String tagToFind = "someTag";
List<Category> categories = getCategoriesList(); // <-- returns a list of Category
Item item = categories.stream()
.flatMap(category -> category.getItems().stream())
.filter(tagToFind.equals(item.getItemTag()))
.findFirst();
但这只搜索项目列表的一个级别.如果我想要更深层次,我可以简单地做:
Item item = categories.stream()
.flatMap(category -> category.getItems().stream())
.flatMap(item->item.getItems().stream()))
.filter(tagToFind.equals(item.getItemTag()))
.findFirst();
哪个工作正常.但我正试图找到一种更具伸缩性的方法来实现这一点,它可以像嵌套列表一样深入.有没有一种有效的方法呢?
解决方法:
您需要一个单独的递归方法.你可以这样做:
Optional<Item> item = categories.stream()
.flatMap(category -> category.getItems().stream())
.flatMap(MyClass::flatMapRecursive)
.filter(i -> tagToFind.equals(i.getItemTag()))
.findFirst();
使用此flatMapRecursive()方法:
public Stream<Item> flatMapRecursive(Item item) {
return Stream.concat(Stream.of(item), item.getItems().stream()
.flatMap(MyClass::flatMapRecursive));
}
还有一件事需要考虑:flatMapRecursive()方法不进行空检查,因此每个项至少需要一个空列表,否则您将获得NullPointerException.
如果项目可以为空值,则可以使用Optional来阻止此项:
public Stream<Item> flatMapRecursive(Item item) {
return Stream.concat(Stream.of(item), Optional.ofNullable(item.getItems())
.orElseGet(Collections::emptyList)
.stream()
.flatMap(MyClass::flatMapRecursive));
}
或者在使用之前对项进行空检查:
public Stream<Item> flatMapRecursive(Item item) {
if (item.getItems() == null) {
return Stream.empty();
}
return Stream.concat(Stream.of(item), item.getItems().stream()
.flatMap(MyClass::flatMapRecursive));
}
标签:nested-lists,java,java-stream,recursion 来源: https://codeday.me/bug/20190827/1744827.html