【问题标题】:Set MathContext to BinaryOperator reference methods将 MathContext 设置为 BinaryOperator 引用方法
【发布时间】:2017-07-17 08:44:49
【问题描述】:

我有这个枚举:

public enum Operator {
    add("+", BigDecimal::add),
    subtract("-", BigDecimal::subtract),
    multiply("*", BigDecimal::multiply),
    divide("/", BigDecimal::divide),
    mod("%", BigDecimal::remainder);

    Operator(final String symbol, final BinaryOperator<BigDecimal> operation) {
        this.symbol = symbol;
        this.operation = operation;
    }

    public BinaryOperator<BigDecimal> getOperation() {
        return operation;
    }
}

我想使用一些MathContext,在执行这样的操作时可以轻松做到这一点:

MathContext mc = MathContext.DECIMAL32;
BigDecimal t0 = new BigDecimal(100);
BigDecimal t1 = new BigDecimal(2); 
BigDecimal result = t0.add(t1, mc);

但是,如果我想在枚举中使用对BinaryOperator 的引用,我看不到给它MathContext 的方法:

BigDecimal result = enum.getOperation().apply(t0, t1);

在文档和可用于应用的方法中,我看到了任何选项。

【问题讨论】:

  • 创建一个使用具有您需要的签名的功能接口。
  • 你也可以用辅助类来包装它,它会消耗 MathContext 和 Operator 枚举。
  • @JBNizet BiFunction 不起作用,因为他需要 TriFunction 之类的东西,因为有三个参数而不是两个(BinaryOperator 实现了 BiFunction,区别只是泛型参数都是相同的类型) .
  • @PascalSchneider 哦,是的,你是对的。谢谢。

标签: java enums java-8 bigdecimal binary-operators


【解决方案1】:

根据用例,您可以将自定义功能接口的范围保持在最低限度:

public enum Operator {
    add("+", BigDecimal::add),
    subtract("-", BigDecimal::subtract),
    multiply("*", BigDecimal::multiply),
    divide("/", BigDecimal::divide),
    mod("%", BigDecimal::remainder);

    private interface TriFunc {
        BigDecimal apply(BigDecimal a, BigDecimal b, MathContext c);
    }
    private String symbol;
    private TriFunc operation;

    Operator(String symbol, TriFunc operation) {
        this.symbol = symbol;
        this.operation = operation;
    }

    public BinaryOperator<BigDecimal> getOperation(MathContext c) {
        return (a, b) -> operation.apply(a, b, c);
    }

    // you can also provide a direct method:
    public BigDecimal apply(BigDecimal a, BigDecimal b, MathContext c) {
        return operation.apply(a, b, c);
    }
}

因此,任何使用Operator 枚举的人都不必了解内部使用的TriFunc 接口。 Operator既可以用,也可以直接点赞

BigDecimal result = Operator.add
    .apply(new BigDecimal(100), new BigDecimal(2), MathContext.DECIMAL32);

或获得标准的BinaryOperator&lt;BigDecimal&gt; 喜欢

BigDecimal result = Operator.add.getOperation(MathContext.DECIMAL32)
    .apply(new BigDecimal(100), new BigDecimal(2));

【讨论】:

    【解决方案2】:

    第一个选项是实现TriFunction&lt;P1, P2, P3, R&gt; 之类的东西并修改您的代码如下:

    public enum Operator {
        add("+", (t0, t1, mc) -> t0.add(t1, mc)),
        subtract("-", (t0, t1, mc) -> t0.subtract(t1, mc)),
        multiply("*", (t0, t1, mc) -> t0.multiply(t1, mc)),
        divide("/", (t0, t1, mc) -> t0.divide(t1, mc)),
        mod("%", (t0, t1, mc) -> t0.remainder(t1, mc));
    
        Operator(final String symbol, final TriFunction<BigDecimal, BigDecimal, MathContext, BigDecimal> operation) {
            this.symbol = symbol;
            this.operation = operation;
        }
    
        public BinaryOperator<BigDecimal, BigDecimal, MathContext, BigDecimal> getOperation() {
            return operation;
        }
    }
    

    但是您必须自己实现TriFunction(或在网上找到它)才能使用,因为 java 没有从头开始提供这样的东西。

    一种更简单(IMO 又快又脏)的方法可能是这样的:

    public enum Operator {
        add("+"), subtract("-"), multiply("*"), divide("/"), mod("%");
    
        // Attributes and constructors
    
        public BigDecimal apply(BigDecimal t1, BigDecimal t2, MathContext mc) {
            switch (this) {
                case add:      return t1.add(t2, mc);
                case subtract: return t1.subtract(t2, mc);
                case multiply: return t1.multiply(t2, mc);
                case divide:   return t1.divide(t2, mc);
                case mod:      return t1.remainder(t2, mc);
            }
            return null; // never reached
        }
    }
    

    你可以更容易地调用它

    BigDecimal result = enum.apply(t0, t1, mc);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 2012-07-16
      • 2017-08-30
      • 2018-06-04
      相关资源
      最近更新 更多