有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

嵌套列表Java中基于日期字段的主列表排序

我有下面的物品清单,需要根据日期前的成分进行分类。因此,最古老的、最好的、最早的食谱应该排在最后

 [
    {
        "id": 2,
        "recipeName": "Burger",
        "createdDate": "2020-11-22T00:00:00.000+00:00",
        "ingredients": [
            {
                "ingredientId": 3,
                "ingredientName": "Burger Bun",
                "category": "",
                "useBy": "2020-12-20",
                "bestBefore": "2020-12-23"
            },
            {
                "ingredientId": 4,
                "ingredientName": "Beef Pattie",
                "category": "",
                "useBy": "2020-12-20",
                "bestBefore": "2020-12-23"
            },
            {
                "ingredientId": 5,
                "ingredientName": "Tomato",
                "category": "",
                "useBy": "2020-12-20",
                "bestBefore": "2020-09-10"
            }
        ]
    },
    {
        "id": 3,
        "recipeName": "Chicken Salad",
        "createdDate": "2020-11-22T00:00:00.000+00:00",
        "ingredients": [
            {
                "ingredientId": 7,
                "ingredientName": "Chicken",
                "category": "",
                "useBy": "2020-12-20",
                "bestBefore": "2020-12-23"
            },
            {
                "ingredientId": 6,
                "ingredientName": "Salad Mix",
                "category": "",
                "useBy": "2020-12-20",
                "bestBefore": "2020-11-15"
            }
        ]
    }
]

我尝试了下面的代码,但它只是对配方中的成分进行排序,而不是列表中的配方对象。这在Java8流中是可能的吗

List<Recipes> finalList = filteredList.stream().sorted((o1, o2) -> (int) (o1.getId() - o2.getId()))
        .map(recipes -> {
            List<Ingredients> in = recipes.getIngredients().stream()
                    .sorted(Comparator.comparing(Ingredients::getBestBefore).reversed()).collect(Collectors.toList());
            recipes.setIngredients(in);
            return recipes;
        }).collect(Collectors.toList());

共 (1) 个答案

  1. # 1 楼答案

    因为你需要确保如果任何成分有最早的bestBefore日期,那么该配方应该排在列表的最后您需要在配方的成分中确定max(最早的)日期,为此您可以创建如下方法:

    private static Date findOldestBestBeforeForRecipe(Recipes recipes) {
        return recipes.getIngredients()
                .stream()
                .map(Ingredients::getBestBefore)
                .max(Comparator.naturalOrder())
                .orElseThrow(() -> new IllegalArgumentException("recipes without ingredients!!"));
    }
    

    然后对你的食谱进行排序,这会简化,比如为这个标准定义一个Comparator<Recipes>,并将它们附加到现有的比较中

    Comparator<Recipes> ingredientsBestBeforeDate = (o1, o2) ->
            findOldestBestBeforeForRecipe(o2).compareTo(findOldestBestBeforeForRecipe(o1));
    
    List<Recipes> finalList = filteredList.stream()
            .sorted(Comparator.comparingInt(Recipes::getId)
                    .thenComparing(ingredientsBestBeforeDate))
            .collect(Collectors.toList());