如何将自定义类的ArrayList转为HashMap?以餐厅菜单查找场景为例
实现方案与问题解答
1. 餐厅内部Menu集合改为HashMap的实现
你场景中需要按菜品名称字符串查询价格,HashMap的key直接设置为菜品名称(String类型)即可,value可以根据业务需要选择两种方案:
- 仅需要查询成本:value直接存菜品价格(
Integer类型),空间开销更小 - 后续需要扩展Menu字段(比如菜品分类、库存等):value存
Menu对象
修改时先修正原代码的笔误(原Restaurant类getCost方法中item.pence与Menu类定义的cost字段不统一),参考代码如下:
修改后的Menu类(无变动)
public class Menu { String item; int cost; }
修改后的Restaurant类(menu改为HashMap,value存Menu对象版本)
public class Restaurant { String name; String location; // key为菜品名称,value为对应的Menu对象 HashMap<String, Menu> menu; public int getCost(String foodItem) { // 直接O(1)查找,不需要遍历 Menu target = menu.get(foodItem); return target != null ? target.cost : 0; } }
如果用value存Integer的简化版本:
public class Restaurant { String name; String location; // key为菜品名称,value为菜品价格 HashMap<String, Integer> menu; public int getCost(String foodItem) { return menu.getOrDefault(foodItem, 0); } }
2. 是否需要替换存储Restaurant的ArrayList为HashMap
取决于你的查询逻辑:
- 如果保留「遍历所有餐厅匹配菜品」的逻辑,不需要替换:因为你查询前不知道菜品属于哪个餐厅,就算把ArrayList换成HashMap(key为餐厅名/ID),你还是需要遍历所有餐厅的value做查询,没有性能收益
- 如果想要进一步优化性能,可以新增全局菜品映射HashMap:因为你明确菜品只会存在于唯一一家餐厅,初始化的时候可以把所有餐厅的所有菜品都写入一个全局的
HashMap<String, Integer> foodToCost(或者HashMap<String, Restaurant> foodToRestaurant),直接通过菜品名一步查到结果,不需要遍历任何集合。
3. 替换后查找逻辑的差异
原逻辑时间复杂度
两层遍历,时间复杂度为O(m*k),其中m是餐厅总数,k是单个餐厅的平均菜品数量
仅替换餐厅内部menu为HashMap后的逻辑
只需要遍历所有餐厅,每个餐厅内部查询为O(1),时间复杂度降到O(m),查询代码简化为:
for (Restaurant restaurant : menuList) { int currentCost = restaurant.getCost(foodItem); if (currentCost > 0) { cost += currentCost; // 因为菜品唯一,找到后可以直接跳出循环,不用遍历剩下的餐厅 break; } }
新增全局菜品映射后的逻辑
不需要遍历,直接O(1)查询,代码简化为:
// 初始化时提前构建的全局映射 HashMap<String, Integer> foodToCost; // 查询逻辑 cost += foodToCost.getOrDefault(foodItem, 0);
内容的提问来源于stack exchange,提问作者Scott Adamson
相关产品推荐
相关产品推荐

