【问题标题】:How to implement BiFunctional function that corresponds to Enum in Java?Java中如何实现Enum对应的BiFunctional函数?
【发布时间】:2019-02-05 14:07:19
【问题描述】:

我有Javaenum

public enum ConflictResolutionStrategy {
    softResolve,
    hardResolve,
}

我想叫它ConflictResolutionStrategy.hardResolve.apply(case1, case2)

case1case2 都是同一类型的对象。 apply 在我的情况下应该什么都不返回。

这个设计背后的基本思想。创建Strategy 设计模式并根据设置的enum 值解决冲突。

我在 StackOveflow 上找不到任何类似的问题,即使简单的搜索给了我大量类似的案例,这些案例并不能直接解决我的案例。

我尝试了以下方法:

public enum ConflictResolutionStrategy {
    softResolve ((CaseType case1, CaseType case2) -> case1.update(case2)),
    hardResolve,
}

以上版本无法编译。

我尝试了另一种解决方案:

public enum ConflictResolutionStrategy {
    softResolve,
    hardResolve {
        public void apply(CaseType case1, CaseType case2) {
            case1.update(case2);
        }
    },
}

第二种解决方案,工作正常,但需要太多代码。

【问题讨论】:

  • 很明显softResolvehardResolve 实际上以不同的方式解决,所以你必须覆盖apply 让他们以不同的方式处理......所以“太多的代码”会是必需的,是的
  • @Eugene 因为softResolvehardResolve 是不同的值,应该区别对待。我确实理解在这两种情况下都应该使用不同的代码。我的问题的重点是否可以以lambda-like 的方式编写,与上一个代码示例中的工作方式相同?我想使用现代Java 功能减少代码购买的噪音。

标签: java lambda enums java-8 functional-interface


【解决方案1】:

接受两个参数但不返回任何内容的函数是BiConsumer

你的枚举可以实现BiConsumer:

public enum ConflictResolutionStrategy implements BiConsumer<CaseType, CaseType> {
    softResolve ((case1, case2) -> case1.update(case2)),
    hardResolve((case1, case2) -> {/* do something else */});

    private final BiConsumer<CaseType, CaseType> consumer;

    ConflictResolutionStrategy(BiConsumer<CaseType, CaseType> consumer){
        this.consumer = consumer;
    }

    @Override
    public void accept(CaseType case1, CaseType case2) {
        consumer.accept(case1, case2);
    }

}

假设您有处理案件的方法:

public void processCases(Collection<CaseType> cases, BiConsumer<CaseType, CaseType> conflictResolutionStrategy){
    // ...
}

现在您可以传入任何一种现有策略:

processCases(cases, ConflictResolutionStrategy.softResolve);

或内联策略:

processCases(cases, (c1, c2) -> { /* do smth here */ }); 

【讨论】:

    【解决方案2】:

    也许您正在枚举中寻找类似 @​​987654321@ 的内容:

    public enum ConflictResolutionStrategy {
        softResolve(CaseType::update), // just for example
        hardResolve((caseType, caseType2) -> {
            caseType.update(caseType2);
        }); // lambda representation
    
        BiConsumer<CaseType, CaseType> caseTypeBiConsumer;
    
        ConflictResolutionStrategy(BiConsumer<CaseType, CaseType> caseTypeBiConsumer) {
            this.caseTypeBiConsumer = caseTypeBiConsumer;
        }
    }
    
    
    class CaseType {
        void update(CaseType caseType){}
    }
    

    【讨论】:

    • 顺便说一句,你会如何使用它?在问题中也提供该示例 - 您会看到您只是将相同的“太多代码”推迟到不同的地方。
    • @Eugene 同意必须在某处编写代码,在这种情况下,update 或其他此类实现将是块。只是提出了更好的绑定类型,并与 OP 尝试过但没有为它们编译的版本相关。
    • @nullpointer 这为我编译,但我如何从我的enum 调用BiConsumer?我尝试类似ConflictResolutionStrategy conflictStrategy = ConflictResolutionStrategy.softResolve; conflictStrategy.accept(case1, case2)accept 方法不可见。我做错了吗?
    • @DmytroChasovskyi 必须是 conflictStrategy.caseTypeBiConsumer.accept
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2023-01-23
    • 2011-01-19
    • 1970-01-01
    • 2012-07-06
    • 2023-03-09
    相关资源
    最近更新 更多