如何压平列表的嵌套地图与Java 8个流?

华达埃琳娜存档:

我有一个看起来像这样的结构:

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,找到一个Item匹配itemTag使用此代码:

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()方法确实没有null检查,所以每个项目至少需要一个空表,否则你将得到一个NullPointerException

如果null值是可能的items,你可以防止这种情况使用Optional

public Stream<Item> flatMapRecursive(Item item) {
    return Stream.concat(Stream.of(item), Optional.ofNullable(item.getItems())
            .orElseGet(Collections::emptyList)
            .stream()
            .flatMap(MyClass::flatMapRecursive));
}

或做的空校验items使用它之前:

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));
}

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章