如何用Java函数式接口实现ProductSettings与ProductType双向配置?
利用函数式接口管理产品类型启用状态
问题背景
现有ProductSettings类与ProductType枚举,ProductSettings用于控制各ProductType的启用状态。已创建两个映射:
mapGetter:ProductType映射至Predicate<ProductSettings>,用于判断对应产品类型是否启用mapSetter:ProductType映射至BiConsumer<ProductSettings, Boolean>,用于设置对应产品类型的启用状态
需完成两项任务:
- 从
ProductSettings实例中提取所有启用的产品类型,填充enabledProductTypes集合 - 根据指定
ProductType,启用对应的ProductSettings配置
解决方案
任务1:填充启用的产品类型集合
通过遍历mapGetter的映射关系,使用Predicate判断每个产品类型的启用状态,将启用的类型加入集合。提供两种实现方式:
普通遍历实现
// 遍历mapGetter,筛选启用的ProductType并加入集合 for (Map.Entry<ProductType, Predicate<ProductSettings>> entry : mapGetter.entrySet()) { ProductType type = entry.getKey(); Predicate<ProductSettings> isEnabled = entry.getValue(); if (isEnabled.test(productSettings)) { enabledProductTypes.add(type); } }
流式API实现(更简洁)
// 用流式API筛选并收集到EnumSet中 enabledProductTypes = mapGetter.entrySet().stream() .filter(entry -> entry.getValue().test(productSettings)) .map(Map.Entry::getKey) .collect(Collectors.toCollection(() -> EnumSet.noneOf(ProductType.class)));
任务2:启用指定产品类型的配置
从mapSetter中取出对应产品类型的BiConsumer,调用其accept方法传入ProductSettings实例和true即可。建议先判断映射是否存在,避免空指针异常:
// 启用指定ProductType的方法 public void enableProductType(ProductType targetType) { BiConsumer<ProductSettings, Boolean> setter = mapSetter.get(targetType); if (setter != null) { setter.accept(productSettings, true); // 同步更新enabledProductTypes集合(可选) enabledProductTypes.add(targetType); } } // 调用示例 enableProductType(ProductType.INFOSWIFT);
补充:补全映射关系
为覆盖所有ProductType枚举值,建议在静态代码块中初始化完整的映射:
static { // 初始化mapGetter mapGetter.put(ProductType.INFO, ProductSettings::getIsTreasuryInfoEnabled); mapGetter.put(ProductType.INFOSWIFT, ProductSettings::getIsTreasurySwiftInfoEnabled); mapGetter.put(ProductType.BUDGETCONTROL, ProductSettings::getIsTreasuryExecutionControlEnabled); mapGetter.put(ProductType.ACCEPT, ProductSettings::getIsAcceptEnabled); // 若DIRECTACCOUNTCONTROL有对应getter,需补充映射 // 初始化mapSetter mapSetter.put(ProductType.INFO, ProductSettings::setIsTreasuryInfoEnabled); mapSetter.put(ProductType.INFOSWIFT, ProductSettings::setIsTreasurySwiftInfoEnabled); mapSetter.put(ProductType.BUDGETCONTROL, ProductSettings::setIsTreasuryExecutionControlEnabled); mapSetter.put(ProductType.ACCEPT, ProductSettings::setIsAcceptEnabled); // 若DIRECTACCOUNTCONTROL有对应setter,需补充映射 }
内容的提问来源于stack exchange,提问作者Aleksandr Berestov
相关产品推荐
相关产品推荐

