【问题标题】:Sort main list based on date field in nested list Java根据嵌套列表Java中的日期字段对主列表进行排序
【发布时间】:2021-03-07 21:26:02
【问题描述】:

我有下面的对象列表,需要根据最佳日期之前的成分对其进行排序。因此,具有最旧保质期的食谱应该排在列表的最后。

 [
    {
        "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"
            }
        ]
    }
]

我尝试了下面的代码,但它只对配方中的成分进行排序,而不是列表中的配方对象。 Java 8 Streams 可以做到这一点吗?

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

【问题讨论】:

  • 当您说根据最佳日期之前的成分进行排序时,要对整个配方进行排序时应考虑哪种成分? (想想bestBefore 值最差和最好的成分是同一个食谱的一部分,这个食谱在你的排序列表中的位置是什么?)
  • @Naman 如果任何成分具有最旧的bestbeforedate,则该配方应排在列表的最后。在这种情况下,Burger 对象应该排在列表的最后,因为番茄拥有最旧的 bestBeforedate

标签: java sorting java-stream


【解决方案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&lt;Recipes&gt; 并将它们附加到现有比较中。

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

【讨论】:

  • 这不是我所期望的结果,任何包含最好之前的成分的食谱(食谱应该根据 bestbefore 排序)日期应该放在列表的底部
  • 编辑后你的答案可以达到List&lt;Recipes&gt; finalList = filteredList.stream().sorted(ingredientsBestBeforeDate).collect(Collectors.toList());的结果@下面的修复findOldestBestBeforeForRecipe.min(Comparator.naturalOrder())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2018-02-25
  • 2017-02-08
相关资源
最近更新 更多