用Java中的流API替换多个FOR循环的最佳方法

问题描述

我想让此功能运行的时间更少。我假设stream()可能会有所帮助。但不确定如何。

private List<TodayMenu> getRecommendedTodayMenuItems(Map<String,Integer> itemsGroupedDailySales,List<TodayMenu> itemsOnTodayMenu) {

    List<TodayMenu> recommendedTodayMenu = new ArrayList<>();

    for (Map.Entry<String,Integer> itemGroupedDailySales : itemsGroupedDailySales.entrySet()) {
        for (TodayMenu todayMenu : itemsOnTodayMenu) {
            if (todayMenu.getMenuId().equals(itemGroupedDailySales.getKey())) {
                recommendedTodayMenu.add(todayMenu);
                break;
            }
        }
        if (recommendedTodayMenu.size() >= 9) {
            return recommendedTodayMenu;
        }
    }
    return recommendedTodayMenu;
}

解决方法

结果仅包含itemsOnTodayMenu的记录,因此您可以开始遍历此列表并在itemsGroupedDailySales中执行查找(HashMap很好)。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

private List<TodayMenu> getRecommendedTodayMenuItemsBetter(Map<String,Integer> itemsGroupedDailySales,List<TodayMenu> itemsOnTodayMenu) {
    return itemsOnTodayMenu.stream()
        .filter((tm)->itemsGroupedDailySales.containsKey(tm.getMenuId()))
        .limit(9)
        .collect(Collectors.toList());
}

一句话:您不使用itemsGroupedDailySales的值。您的逻辑在前9个匹配项之后停止,但未定义顺序。例如,不是按建议选择的销量最高的商品。希望您知道这一点。

,

您应该在地图中通过id为您的itemsOnTodayMenu编制索引。您可以节省从O(n * m)到O(n + m)的时间。

  • 迭代itemsOnTodayMenu来构建地图
  • item itemsGroupedDailySales
    • 从地图上按ID获取“今天”菜单
,

您打算最多在外循环的内循环中找到一个元素。因此,您需要在主体结构上使用map,使用filter来检查是否具有相等条件,然后调用findFirst来实现初始代码中的break的行为。要limit个结果数,请使用相同的名称调用该方法。

我会为此编写一些代码,但是我对Java流没有经验,并且没有测试我编写的任何代码的方法。因此,请尝试实施这个想法,并确保告诉我它的进展。