首页 > 解决方案 > 列表包含另一个列表,并且基于逻辑主列表应该修改

问题描述

我有一个对象列表,如下所示。如果任何成分超过使用日期,则结果列表不应包含食谱。这是否可以通过 Java Streams 实现。

我试图像下面那样做,但出现编译错误。非常感谢您的回复,因为我正在努力寻找答案。

List<Recipes> filteredList =
    recipeList.stream().filter(recipes -> recipes.getIngredients().stream().filter(ingredients -> ingredients.getUseBy().before(lunchDate)).collect(Collectors.toList()));
    [
        {
            "id": 1,
            "recipeName": "Pasta",
            "createdDate": "2020-11-22T00:00:00.000+00:00",
            "ingredients": [
                {
                    "ingredientId": 1,
                    "ingredientName": "Shells",
                    "useBy": "2020-11-20",
                    "bestBefore": "2020-11-18"
                },
                {
                    "ingredientId": 2,
                    "ingredientName": "Mozaralla Cheese",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-11-23"
                }
            ]
        },
        {
            "id": 2,
            "recipeName": "Burger",
            "createdDate": "2020-11-22T00:00:00.000+00:00",
            "ingredients": [
                {
                    "ingredientId": 3,
                    "ingredientName": "Burger Bun",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-12-23"
                },
                {
                    "ingredientId": 4,
                    "ingredientName": "Beef Pattie",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-12-23"
                },
                {
                    "ingredientId": 5,
                    "ingredientName": "Tomato",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-12-23"
                }
            ]
        },
        {
            "id": 3,
            "recipeName": "Chicken Salad",
            "createdDate": "2020-11-22T00:00:00.000+00:00",
            "ingredients": [
                {
                    "ingredientId": 6,
                    "ingredientName": "Salad Mix",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-11-15"
                },
                {
                    "ingredientId": 7,
                    "ingredientName": "Chicken",
                    "useBy": "2020-12-20",
                    "bestBefore": "2020-12-23"
                }
            ]
        }
    ]

标签: javalistjava-stream

解决方案


Stream().filter()接受一个Predicate<T>作为参数并返回一个由该流中与给定谓词匹配的元素组成的流。您的要求可以改写为:

List<Recipes> filteredList = recipeList.stream().filter(predicate: recipes does not contain any ingredient past useBy date).collect(Collectors.toList()));

并且您的问题已更改为编写匹配的谓词:食谱不包含任何useBy过期的成分。(对于任何食谱,计算成分通过useBy日期,计数应为 0。)

你可以使用另一个stream().filter(predicate: count ingredient after useBy date, and it should be 0)

recipes -> recipes.getIngredients().stream()
    .filter(ingredients -> ingredients.getUseBy().after(lunchDate))
    .collect(Collectors.toList()).size() == 0

然后将谓词添加到您的第一个过滤器表达式。最后的表达式是这样的:

List<Recipes> filteredList = recipeList.stream().filter(
    recipes -> recipes.getIngredients().stream()
        .filter(ingredients -> ingredients.getUseBy().after(lunchDate))
        .collect(Collectors.toList()).size() == 0
).collect(Collectors.toList()));

推荐阅读