将MathContext设置为BinaryOperator引用方法

时间:2017-02-26 20:29:46

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

我有这个枚举:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System.Threading;

public class Player : MonoBehaviour {

public Vector2 jumpForce = new Vector2(0, 300);
private Rigidbody2D rb2d;
Generator SwagScript;
GameObject generator;



// Use this for initialization
void Start () {
    rb2d = gameObject.GetComponent<Rigidbody2D>();
    generator = GameObject.FindGameObjectWithTag("Generator");
    SwagScript = generator.GetComponent<Generator>();
}

// Update is called once per frame
void Update () {
    if (Input.GetKeyUp("space"))
    {
        rb2d.velocity = Vector2.zero;
        rb2d.AddForce(jumpForce);
    }

    Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
    if (screenPosition.y > Screen.height || screenPosition.y < 0)
    {
        Die();
    }
}

void OnCollisionEnter2D(Collision2D other)
{
    Die();
}

void Die()
{
    if (PlayerPrefs.HasKey("HighScore"))
    {
        if (PlayerPrefs.GetInt("Highscore") < SwagScript.score)
        {
            PlayerPrefs.SetInt("HighScore", SwagScript.score);
        }
        else
        {
            PlayerPrefs.SetInt("HighScore", SwagScript.score);
        }
    }
    Application.LoadLevel(Application.loadedLevel);
}

我想使用一些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

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

2 个答案:

答案 0 :(得分:3)

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

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<BigDecimal>

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

答案 1 :(得分:2)

第一个选项是实现TriFunction<P1, P2, P3, R>之类的内容并修改代码如下:

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);