Java 创建自定义BigDecimal类型
在我的应用程序中,所有BigDecimal数字都被缩放为两位小数。。换句话说,每次我在代码中创建新的BigDecimal时,我也需要使用scale方法: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 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这就是为什么我指出在另一个答案中建议的实用程序类更好。