如何实现参数化算法

时间:2015-12-11 15:53:56

标签: java generics bigdecimal primitive

我正在设计一个库,它提供了大量的类,这些类使用数字执行繁重的操作。我不希望将库的用户限制为单个数字类型,例如intdoubleBigDecimal - 因此,如果我可以使用泛型来允许用户选择自己的号码类型。我可以使用原始包装类而不是原语本身所带来的开销,这对于使用泛型来说是必要的,但我的问题在于执行算术。

如果我创建了一个假设类MathematicalObject<N extends Number>,那么用户可以使用任何类型来存储扩展数字的数字 - IntegerDoubleBigDecimal等等。但是Number类没有为算术提供任何接口 - 我不能添加两个Number而不将它们转换为double或类似的东西 - 这可能会影响数字的准确性(例如,如果使用BigDecimal)。

那么,我可以实现参数化数字使用的最高效的方法是什么,这使得我可以执行算术运算?

2 个答案:

答案 0 :(得分:2)

您可以使用工厂创建MathematicalObject。 MathematicalObject的构造函数可以接受专门用于对参数化类型执行数学运算的策略类,工厂只根据参数化类型选择正确的策略类。

public class MathemeaticalObject<N extends Number> {
    private final NumberOperations<N> ops;
    public MatchematicalObject(NumberOperations<N> ops) {
        this.ops = ops;
    }

    public N myComplexOperation(N other) {
        return ops.add(this, other);
    }
}

public class MathematicalObjectFactory {
    MathematicalObject<Integer> integerObject() {
        return new MathematicalObject(new IntegerOperations());
    }
    ....
}

public interface NumberOperations<N extends Number> {
    N add(N other);
}

public class IntegerOperations implements NumberOperations<Integer> {
    @Override
    public Integer add(Integer first, Integer second) {
        return first + second;
    }
}

缺点是你只能支持N的值。但我认为可能没有办法解决这个问题。考虑到原始数学运算不能直接获得,它也可能会产生一些混乱的代码。

答案 1 :(得分:0)

您可以为aritmethic操作定义自己的界面。 对于使用BigInteger或类似的类,您可以只是对类进行子类化并使子类实现您的接口。 对于原始类型,您必须编写自己的Wrapper类:(

这是设计模式适配器:https://en.wikipedia.org/wiki/Adapter_pattern