Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建自定义BigDecimal类型_Java_Bigdecimal - Fatal编程技术网

Java 创建自定义BigDecimal类型

Java 创建自定义BigDecimal类型,java,bigdecimal,Java,Bigdecimal,在我的应用程序中,所有BigDecimal数字都被缩放为两位小数。。换句话说,每次我在代码中创建新的BigDecimal时,我也需要使用scale方法: BigDecimal x = BigDecimal.ZERO; x.setScale(2, RoundingMode.HALF_UP); 因此,为了尽量减少工作量,我想创建我的自定义BigDecimal类型,类似于: public class CustomBigDecimal extends BigDecimal { public

在我的应用程序中,所有BigDecimal数字都被缩放为两位小数。。换句话说,每次我在代码中创建新的BigDecimal时,我也需要使用scale方法:

BigDecimal x = BigDecimal.ZERO;
x.setScale(2, RoundingMode.HALF_UP);
因此,为了尽量减少工作量,我想创建我的自定义BigDecimal类型,类似于:

public class CustomBigDecimal extends BigDecimal {

    public CustomBigDecimal(String val) {
        super(val);
        this.setScale(2, RoundingMode.HALF_UP);
    }

}
public static BigDecimal scaled(String val) {
    BigDecimal x = new BigDecimal(val);
    return x.setScale(2, RoundingMode.HALF_UP);
}

我知道
这个.setScale(2,取整模式,半向上)
不做这项工作,但我找不到方法来做,可能吗?

您可以为自己创建一个方法,创建一个带零的BigDecimal。比如:

public class CustomBigDecimal extends BigDecimal {

    public CustomBigDecimal(String val) {
        super(val);
        this.setScale(2, RoundingMode.HALF_UP);
    }

}
public static BigDecimal scaled(String val) {
    BigDecimal x = new BigDecimal(val);
    return x.setScale(2, RoundingMode.HALF_UP);
}
把它放在一个helper类中,比如BigDecimalHelper、BigDecimalFactory或其他任何东西。:)


编辑:稍微更改它以返回setScale的结果,因为BigDecimal是不可变的。为了进一步回答最初的问题:不,您所写的是不可能的,因为对象的状态没有使用setScale()更改。

例如,您可以存储MathContext的单例实例,并将其用作BigDecimal构造函数的参数

通常你可以做:

MathContext context = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal number = new BigDecimal(val, context);
因此,如果将MathContext设置为singleton,则可以执行以下操作:

BigDecimal number = new BigDecimal(val, MathInstanceHolder.getMathContext());

其中MathInstanceHolder包含MathContext实例。

您可以创建一个扩展自
BigDecimal
CustomBigDecimal
。但是,由于
BigDecimal
是不可变的,因此您永远不会从父类继承状态(例如比例和舍入模式)

我会选择另一个答案中建议的实用程序类,或者是一个将每个操作委托给实际的
BigDecimal
实例的包装器。这种方法的缺点是,您全新的
CustomBigDecimal
不是
BigDecimal
,因此它们不能互换

编辑:这种方法的一个缺点是您必须委派大约50个方法。没有一个好的IDE不是世界末日,但肯定不是很吸引人

毕竟,如果您仍然希望使
CustomBigDecimal
继承自
BigDecimal
,则需要使用装饰器方法:

public class CustomBigDecimal extends BigDecimal {

    private final BigDecimal value;

    private CustomBigDecimal(BigDecimal value) {
        super(value.toPlainString()); // needed to compile, 
                                      // useless except for implicit null-check
        this.value = value;
    }

    public CustomBigDecimal(String val) {
        this(new BigDecimal(val).setScale(2, RoundingMode.HALF_UP));
    }

    @Override
    public CustomBigDecimal abs() {
        return new CustomBigDecimal(this.value.abs());
    }

    // TODO all other methods

}

为了与众不同并利用Java 8,您也可以使用lambda解决这个问题:

public static Function<String, BigDecimal> SCALED_BIG_DECIMAL = (val) -> new BigDecimal(val).setScale(2, RoundingMode.HALF_UP);
...

// and this is how you would use it
SCALED_BIG_DECIMAL.apply("20.2343425")
公共静态函数SCALED\u BIG\u DECIMAL=(val)->新的bigdcimal(val).setScale(2,舍入模式.半向上);
...
//这就是你将如何使用它
按比例的大小数点。应用(“20.2343425”)


zero被用作一个例子。@MarcusWidegren是的,这是一个很好的方法!但我真的想知道是否有办法创建自定义的BigDecimal类型。。不管怎样,如果没有人能帮助我自定义这个类型,我会考虑这个答案,谢谢回答:如果BigDecimal没有被声明为最终的,它可能是它的子类,因为它应该是不可变的,但是它不能解决你的问题,因为它的状态在创建之后不会改变。如果您想要自定义类型,我会选择一个具有BigDecimal而不是is 1的类型。这样,您就可以在构造函数中创建BigDecimal并更改其状态。:)无论如何,为您的用例创建一个特殊类型可能是一个好主意。例如,一种货币类型。。如果我明白了,你是在告诉我创建一个customBigDecimal,里面有一个BigDecimal变量,对吗@MarcusWidegren为什么不使用委托给BigDecimal的自定义类型?请注意,
x.setScale
不会更改
x
的比例,而是返回一个具有相同值(可能四舍五入)和比例2的新BigDecimal对象。您必须将其分配给变量才能产生任何效果。谦虚地说,我更喜欢这种方法,而不是包装器。我建议使用singleton实例,因为该值在应用程序范围内永远不会更改,并且将用于所有BigDecimal实例。通过这种方式,您可以像往常一样使用BigDecimal,并且对于读取代码的任何其他开发来说,刻度都是清晰的。我只是把责任分开,但这是主观的。建议总是受欢迎的。我的错。我误解了你的建议。我将删除我的评论。哇,我真的很喜欢这种方法。。我同意你所说的,我的大小数唯一特别的地方就是小数点后2位,所以如果我像你说的那样创建一个单例,我可以像往常一样使用普通的大小数,并且仍然可以在构造函数中设置比例。。太棒了,谢谢@Danilogomes请注意,由于MathContext精度与BigDecimal.setScale不同,此解决方案将无法工作。您认为我是否在其他时间更改BigDecimal.setScale?谢谢您的回答!虽然我选择了Danilo Gomes answer在我的应用程序中实现,但我会将它设置为正确的,因为它回答了最初的问题。感谢@MarcusWidegren,因为他在一条评论中也提出了这种方法。@polska感谢你!我也相信Danilo的答案比这个方法更好,尽管我不会使用singleton部分。然而,我认为@Marcus方法是最好的,因为您不需要每次创建新的
BigDecimal
时都使用上下文。如果您或其他开发人员忘记传递上下文参数呢?嗯。。你是对的,我们实际上是2,我认为其他开发人员继续像往常一样创建BigDecimal会更好(没有param这样的上下文),它更直观,也更简单!谢谢:)大约有50种方法可以委派。这在我看来是个坏主意。@Marco13这就是为什么我指出在另一个答案中建议的实用程序类更好。