Java嵌套Map / List-按列表内容过滤,返回父对象

时间:2019-06-21 22:22:14

标签: java list dictionary java-stream

我对函数有两个字符串参数-“ Pizza”和“ Chips”。我想使用流返回作者,该作者的“食物”键具有与这两个字符串匹配的内容

List<String> collection = Arrays.asList("Pizza", "Chips");


private static List<Map<String, Object>> authors = Arrays.asList(
    ImmutableMap.of("id", "author-1",
                            "firstName", "Adam",
                            "lastName", "Awldridge",
                            "foods", Arrays.asList("Pizza", "Chips")),
    ImmutableMap.of("id", "author-2",
                        "firstName", "Bert",
                        "lastName", "Bruce",
                        "foods", Arrays.asList("Pizza", "Fish")),
        ... // other authors
        );

这是我对流的尝试:

return authors
                    .stream()
                    .filter(authors.stream()
                            .flatMap(author -> author.get("foods"))
                            .findAny(queryFoods))
                    .findFirst().orElse(null);

我想返回食物与我的查询相符的第一作者。我认为主要的困难是组织数据-不幸的是,我无法完成以下的工作。

.flatMap(author -> (List<String>) author.get("foods"))

此外,这可能会流过作者太多次(我应该在刚刚制作的流中使用.filter

authors.stream()

3 个答案:

答案 0 :(得分:2)

在这里您不能直接将食品密钥的值视为列表。它只是一个对象。因此,首先需要检查一个实例,如果它是List的实例,那么可以检查它是否包含集合中的值。

Map<String,Object> firstAuthor =  authors
                                        .stream()
                                        .filter(author -> {
                                            Object foods = author.get("foods");
                                            if(foods instanceof List) {
                                                List foodsList = (List) foods;
                                                return foodsList.containsAll(collection);
                                            }
                                            return false;
                                        })
                                       .findFirst().orElse(null);

输出: {id = author-1,firstName = Adam,lastName = Awldridge,foods = [Pizza,Chips]}

以上代码将为您提供所需的作者(如果存在),否则为null。 [这里,我假设您要检查作者是否拥有您创建的收集对象中存在的所有食品。如果仅要检查一项,则可以使用java.util.List中的 contains()方法,而不是 containsAll()方法。另外,您将必须遍历集合对象以检查集合中的每个项目。]

答案 1 :(得分:1)

我可以通过在流中过滤来解决它:

Map<String,Object> author =  authors.stream()
                                    .filter(a -> a.containsKey("foods"))
                                    .filter(a -> a.get("foods") instanceof List)
                                    .filter(a -> ((List) a.get("foods")).containsAll(collection))
                                    .findFirst().orElse(null);

答案 2 :(得分:0)

也许这就是您想要的?

         authors
                    .stream()
                    .filter(a -> a.get("foods").stream().anyMatch(x -> "Pizza".equals(x)))
                    .findFirst().orElse(null);