如何将对象类型/引用作为HashMap的值?车库初始化实现问询
嘿,这个需求其实挺典型的,用工厂模式+HashMap就能完美解决!我给你捋捋具体的实现思路,一步步来:
1. 先定义对应车辆的创建逻辑
首先,我们需要把「字符code→对应Vehicle子类实例」的映射逻辑封装起来。因为每个code对应一个无参(或带code参数)的对象创建动作,用Java的函数式接口刚好合适:
- 如果你的子类是无参构造(后续再设置code属性),用
Supplier<Vehicle>就够了——它就是个无参的“工厂函数”,负责产出对应对象。 - 如果你的子类需要把code传入构造方法(比如每个实例要自己持有code),那就用
Function<Character, Vehicle>——它接收一个char参数,返回对应的Vehicle对象。
2. 初始化你的HashMap映射表
接下来我们把这个映射关系提前塞进HashMap里,做成静态常量最好,这样整个应用只初始化一次,省资源:
情况1:子类用无参构造
// 可以放在GarageService或者单独的工厂类里 private static final Map<Character, Supplier<Vehicle>> VEHICLE_FACTORY = new HashMap<>(); // 静态代码块初始化,程序启动时就加载好 static { VEHICLE_FACTORY.put('M', Motorcycle::new); VEHICLE_FACTORY.put('C', Car::new); VEHICLE_FACTORY.put('B', Bus::new); }
情况2:子类需要接收code参数的构造方法
private static final Map<Character, Function<Character, Vehicle>> VEHICLE_FACTORY = new HashMap<>(); static { // 用lambda或者方法引用都可以,只要构造方法匹配参数就行 VEHICLE_FACTORY.put('M', code -> new Motorcycle(code)); VEHICLE_FACTORY.put('C', Car::new); // 如果Car的构造是Car(char code),直接用方法引用更简洁 VEHICLE_FACTORY.put('B', Bus::new); }
3. 在Garage初始化时用这个Map创建车辆
拿到构造方法传入的字符串(比如"MMCB")后,遍历每个字符,从Map里取出对应的工厂逻辑,创建对象加入ArrayList:
对应无参构造的写法
public Garage(String codeStr) { this.vehicles = new ArrayList<>(); for (char code : codeStr.toCharArray()) { Supplier<Vehicle> vehicleFactory = VEHICLE_FACTORY.get(code); if (vehicleFactory != null) { Vehicle vehicle = vehicleFactory.get(); // 如果需要设置code,这里可以加一行vehicle.setCode(code); vehicles.add(vehicle); } else { // 处理未知code的情况,比如抛异常或者跳过 throw new IllegalArgumentException("Unknown vehicle code: " + code); } } }
对应带参数构造的写法
public Garage(String codeStr) { this.vehicles = new ArrayList<>(); for (char code : codeStr.toCharArray()) { Function<Character, Vehicle> vehicleFactory = VEHICLE_FACTORY.get(code); if (vehicleFactory != null) { // 直接把当前code传给工厂函数,创建带code的实例 Vehicle vehicle = vehicleFactory.apply(code); vehicles.add(vehicle); } else { throw new IllegalArgumentException("Unknown vehicle code: " + code); } } }
4. 额外的优化小技巧
- 把这个HashMap放在GarageService里,让Garage依赖GarageService来获取车辆实例,符合单一职责原则——Garage只管管理车辆列表,GarageService负责车辆的创建逻辑。
- 后续如果要新增Vehicle子类(比如Truck,code是"T"),只需要在Map里加一行
VEHICLE_FACTORY.put('T', Truck::new),完全不用修改Garage的初始化代码,完美符合开闭原则。
内容的提问来源于stack exchange,提问作者redd77
相关产品推荐
相关产品推荐

