
cn.basics.util.extend.MoneyUtil Maven / Gradle / Ivy
package cn.basics.util.extend;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Currency;
/**
* 单币种货币类,处理货币算术、币种和取整。
*
* 货币类中封装了货币金额和币种。目前金额在内部是long类型表示,
* 单位是所属币种的最小货币单位(对人民币是分)。
*
* 目前,货币实现了以下主要功能:
*
* - 支持货币对象与double(float)/long(int)/String/BigDecimal之间相互转换。
*
- 货币类在运算中提供与JDK中的BigDecimal类似的运算接口,BigDecimal的运算接口支持任意指定精度的运算功能,能够支持各种可能的财务规则。
*
- 货币类在运算中也提供一组简单运算接口,使用这组运算接口,则在精度处理上使用缺省的处理规则。
*
- 推荐使用MoneyUtil,不建议直接使用BigDecimal的原因之一在于,使用BigDecimal,同样金额和币种的货币使用BigDecimal存在多种可能
* 的表示,例如:new BigDecimal("10.5")与new BigDecimal("10.50")不相等,因为scale不等。使得Money类,同样金额和币种的货币只有
* 一种表示方式,new MoneyUtil("10.5")和new MoneyUtil("10.50")应该是相等的。
*
- 不推荐直接使用BigDecimal的另一原因在于, BigDecimal是Immutable,一旦创建就不可更改,对BigDecimal进行任意运算都会生成一个新的
* BigDecimal对象,因此对于大批量统计的性能不够满意。MoneyUtil类是mutable的,对大批量统计提供较好的支持。
*
- 提供基本的格式化功能。
*
- MoneyUtil类中不包含与业务相关的统计功能和格式化功能。业务相关的功能建议使用utility类来实现。
*
- MoneyUtil类实现了Serializable接口,支持作为远程调用的参数和返回值。
*
- MoneyUtil类实现了equals和hashCode方法。
*
* @ClassName: MoneyUtil
* @Description: TODO(单币种货币类,处理货币算术、币种和取整)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午3:55:55
*/
public class MoneyUtil implements Serializable, Comparable {
private static final long serialVersionUID = 6009335074727417445L;
/**缺省的币种代码,为CNY(人民币)*/
public static final String DEFAULT_CURRENCY_CODE = "CNY";
/**缺省的取整模式,为BigDecimal.ROUND_HALF_EVEN(四舍五入,当小数为0.5时,则取最近的偶数)*/
public static final int DEFAULT_ROUNDING_MODE = BigDecimal.ROUND_HALF_EVEN;
/**一组可能的元/分换算比例。此处,“分”是指货币的最小单位,“元”是货币的最常用单位,不同的币种有不同的元/分换算比例,如人民币是100,而日元为1*/
private static final int[] centFactors = new int[] { 1, 10, 100, 1000 };
/**金额,以分为单位*/
private long cent;
/**币种*/
private Currency currency;
// 构造器 ====================================================
/**缺省构造器。
创建一个具有缺省金额(0)和缺省币种的货币对象。*/
public MoneyUtil() {
this(0);
}
/**
* 构造器。
*
创建一个具有金额yuan
元cent分和缺省币种的货币对象。
*@param yuan 金额元数。
* @param cent 金额分数。
*/
public MoneyUtil(long yuan, int cent) {
this(yuan, cent, Currency.getInstance(DEFAULT_CURRENCY_CODE));
}
/**
* 构造器。
* 创建一个具有金额yuan
元cent
分和指定币种的货币对象。
* @param yuan 金额元数。
* @param cent 金额分数。
*/
public MoneyUtil(long yuan, int cent, Currency currency) {
this.currency = currency;
this.cent = (yuan * getCentFactor()) + (cent % getCentFactor());
}
/**
* 构造器。
*
创建一个具有金额amount
元和缺省币种的货币对象。
* @param amount 金额,以元为单位。
*/
public MoneyUtil(String amount) {
this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
}
/**
* 构造器。
*
创建一个具有金额amount
元和指定币种currency
的货币对象。
* @param amount 金额,以元为单位。
* @param currency 币种。
*/
public MoneyUtil(String amount, Currency currency) {
this(new BigDecimal(amount), currency);
}
/**
* 构造器。
*
创建一个具有金额amount
元和指定币种currency
的货币对象。
* 如果金额不能转换为整数分,则使用指定的取整模式roundingMode
取整。
* @param amount 金额,以元为单位。
* @param currency 币种。
* @param roundingMode 取整模式。
*/
public MoneyUtil(String amount, Currency currency, int roundingMode) {
this(new BigDecimal(amount), currency, roundingMode);
}
/**
* 构造器。
*
创建一个具有参数amount
指定金额和缺省币种的货币对象。
* 如果金额不能转换为整数分,则使用四舍五入方式取整。
*
注意:由于double类型运算中存在误差,使用四舍五入方式取整的
* 结果并不确定,因此,应尽量避免使用double类型创建货币类型。
* 例:
*
* assertEquals(999, Math.round(9.995 * 100));
* assertEquals(1000, Math.round(999.5));
* money = new Money((9.995));
* assertEquals(999, money.getCent());
* money = new Money(10.005);
* assertEquals(1001, money.getCent());
*
* @param amount 金额,以元为单位。
*/
public MoneyUtil(double amount) {
this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
}
/**
* 构造器。
*
创建一个具有金额amount
和指定币种的货币对象。
* 如果金额不能转换为整数分,则使用四舍五入方式取整。
*
注意:由于double类型运算中存在误差,使用四舍五入方式取整的
* 结果并不确定,因此,应尽量避免使用double类型创建货币类型。
* 例:
*
* assertEquals(999, Math.round(9.995 * 100));
* assertEquals(1000, Math.round(999.5));
* money = new Money((9.995));
* assertEquals(999, money.getCent());
* money = new Money(10.005);
* assertEquals(1001, money.getCent());
*
* @param amount 金额,以元为单位。
* @param currency 币种。
*/
public MoneyUtil(double amount, Currency currency) {
this.currency = currency;
this.cent = Math.round(amount * getCentFactor());
}
/**
* 构造器。
*
创建一个具有金额amount
和缺省币种的货币对象。
* 如果金额不能转换为整数分,则使用缺省取整模式DEFAULT_ROUNDING_MODE
取整。
* @param amount 金额,以元为单位。
*/
public MoneyUtil(BigDecimal amount) {
this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE));
}
/**
* 构造器。
*
创建一个具有参数amount
指定金额和缺省币种的货币对象。
* 如果金额不能转换为整数分,则使用指定的取整模式roundingMode
取整。
* @param amount 金额,以元为单位。
* @param roundingMode 取整模式
*/
public MoneyUtil(BigDecimal amount, int roundingMode) {
this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE), roundingMode);
}
/**
* 构造器。
*
创建一个具有金额amount
和指定币种的货币对象。
* 如果金额不能转换为整数分,则使用缺省的取整模式DEFAULT_ROUNDING_MODE
进行取整。
* @param amount 金额,以元为单位。
* @param currency 币种
*/
public MoneyUtil(BigDecimal amount, Currency currency) {
this(amount, currency, DEFAULT_ROUNDING_MODE);
}
/**
* 构造器。
*
创建一个具有金额amount
和指定币种的货币对象。
* 如果金额不能转换为整数分,则使用指定的取整模式roundingMode
取整。
* @param amount 金额,以元为单位。
* @param currency 币种。
* @param roundingMode 取整模式。
*/
public MoneyUtil(BigDecimal amount, Currency currency, int roundingMode) {
this.currency = currency;
this.cent = rounding(amount.movePointRight(currency.getDefaultFractionDigits()),
roundingMode);
}
// Bean方法 ====================================================
/**
*
* @Title: getAmount
* @Description: TODO(获取本货币对象代表的金额数。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:01:58
* @return 金额数,以元为单位。
*/
public BigDecimal getAmount() {
return BigDecimal.valueOf(cent, currency.getDefaultFractionDigits());
}
/**
* @Title: setAmount
* @Description: TODO(设置本货币对象代表的金额数。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:02:29
* @param amount 金额数,以元为单位。
*/
public void setAmount(BigDecimal amount) {
if (amount != null) {
cent = rounding(amount.movePointRight(2), BigDecimal.ROUND_HALF_EVEN);
}
}
/**
* @Title: getCent
* @Description: TODO(获取本货币对象代表的金额数。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:03:02
* @return 金额数,以元为单位。
*/
public long getCent() {
return cent;
}
/**
* @Title: getCurrency
* @Description: TODO(获取本货币对象代表的币种。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:03:22
* @return 本货币对象所代表的币种。
*/
public Currency getCurrency() {
return currency;
}
/**
* @Title: getCentFactor
* @Description: TODO(获取本货币币种的元/分换算比率。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:03:43
* @return 本货币币种的元/分换算比率。
*/
public int getCentFactor() {
return centFactors[currency.getDefaultFractionDigits()];
}
// 基本对象方法 ===================================================
/**
* 判断本货币对象与另一对象是否相等。
*
* 本货币对象与另一对象相等的充分必要条件是:
*
* - 另一对象也属货币对象类。
*
- 金额相同。
*
- 币种相同。
*
* @param other 待比较的另一对象。
* @return true
表示相等,false
表示不相等。
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
return (other instanceof MoneyUtil) && equals((MoneyUtil) other);
}
/**
* 判断本货币对象与另一货币对象是否相等。
*
*
* 本货币对象与另一货币对象相等的充分必要条件是:
*
* - 金额相同。
*
- 币种相同。
*
*
* @param other 待比较的另一货币对象。
* @return true
表示相等,false
表示不相等。
*/
public boolean equals(MoneyUtil other) {
return currency.equals(other.currency) && (cent == other.cent);
}
/**
* 计算本货币对象的杂凑值。
* @return 本货币对象的杂凑值。
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (int) (cent ^ (cent >>> 32));
}
// Comparable接口 ========================================
/**
* 对象比较。
*
* 比较本对象与另一对象的大小。
* 如果待比较的对象的类型不是Money
,则抛出java.lang.ClassCastException
。
* 如果待比较的两个货币对象的币种不同,则抛出java.lang.IllegalArgumentException
。
* 如果本货币对象的金额少于待比较货币对象,则返回-1。
* 如果本货币对象的金额等于待比较货币对象,则返回0。
* 如果本货币对象的金额大于待比较货币对象,则返回1。
* @param other 另一对象。
* @return -1表示小于,0表示等于,1表示大于。
* @exception ClassCastException 待比较货币对象不是Money
。
* IllegalArgumentException 待比较货币对象与本货币对象的币种不同。
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(MoneyUtil other) {
assertSameCurrencyAs(other);
if (cent < other.cent) {
return -1;
} else if (cent == other.cent) {
return 0;
} else {
return 1;
}
}
/**
* @Title: greaterThan
* @Description: TODO(货币比较。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:18:28
*
* 判断本货币对象是否大于另一货币对象。
* 如果待比较的两个货币对象的币种不同,则抛出java.lang.IllegalArgumentException
。
* 如果本货币对象的金额大于待比较货币对象,则返回true,否则返回false。
* @param other 另一对象。
* @return true表示大于,false表示不大于(小于等于)。
* @exception IllegalArgumentException 待比较货币对象与本货币对象的币种不同。
*/
public boolean greaterThan(MoneyUtil other) {
return compareTo(other) > 0;
}
// 货币算术 ==========================================
/**
* @Title: add
* @Description: TODO(货币加法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:18:05
*
* 如果两货币币种相同,则返回一个新的相同币种的货币对象,其金额为
* 两货币对象金额之和,本货币对象的值不变。
* 如果两货币对象币种不同,抛出java.lang.IllegalArgumentException
。
* @param other 作为加数的货币对象。
* @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
* @return 相加后的结果。
*/
public MoneyUtil add(MoneyUtil other) {
assertSameCurrencyAs(other);
return newMoneyWithSameCurrency(cent + other.cent);
}
/**
* @Title: addTo
* @Description: TODO(货币累加。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:17:43
*
* 如果两货币币种相同,则本货币对象的金额等于两货币对象金额之和,并返回本货币对象的引用。
* 如果两货币对象币种不同,抛出java.lang.IllegalArgumentException
。
* @param other 作为加数的货币对象。
* @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
* @return 累加后的本货币对象。
*/
public MoneyUtil addTo(MoneyUtil other) {
assertSameCurrencyAs(other);
this.cent += other.cent;
return this;
}
/**
* @Title: subtract
* @Description: TODO(货币减法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:17:20
*
* 如果两货币币种相同,则返回一个新的相同币种的货币对象,其金额为
* 本货币对象的金额减去参数货币对象的金额。本货币对象的值不变。
* 如果两货币币种不同,抛出java.lang.IllegalArgumentException
。
* @param other 作为减数的货币对象。
* @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
* @return 相减后的结果。
*/
public MoneyUtil subtract(MoneyUtil other) {
assertSameCurrencyAs(other);
return newMoneyWithSameCurrency(cent - other.cent);
}
/**
* @Title: subtractFrom
* @Description: TODO(货币累减。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:16:51
*
* 如果两货币币种相同,则本货币对象的金额等于两货币对象金额之差,并返回本货币对象的引用。
* 如果两货币币种不同,抛出java.lang.IllegalArgumentException
。
* @param other 作为减数的货币对象。
* @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
* @return 累减后的本货币对象。
*/
public MoneyUtil subtractFrom(MoneyUtil other) {
assertSameCurrencyAs(other);
this.cent -= other.cent;
return this;
}
/**
* @Title: multiply
* @Description: TODO(货币乘法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:16:21
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
* 本货币对象的值不变。
* @param val 乘数
* @return 乘法后的结果。
*/
public MoneyUtil multiply(long val) {
return newMoneyWithSameCurrency(cent * val);
}
/**
* @Title: multiplyBy
* @Description: TODO(货币累乘。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:15:58
*
* 本货币对象金额乘以乘数,并返回本货币对象。
* @param val 乘数
* @return 累乘后的本货币对象。
*/
public MoneyUtil multiplyBy(long val) {
this.cent *= val;
return this;
}
/**
* @Title: multiply
* @Description: TODO(货币乘法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:15:30
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
* 本货币对象的值不变。如果相乘后的金额不能转换为整数分,则四舍五入。
* @param val 乘数
* @return 相乘后的结果。
*/
public MoneyUtil multiply(double val) {
return newMoneyWithSameCurrency(Math.round(cent * val));
}
/**
* @Title: multiplyBy
* @Description: TODO(货币累乘。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:14:59
*
* 本货币对象金额乘以乘数,并返回本货币对象。
* 如果相乘后的金额不能转换为整数分,则使用四舍五入。
* @param val 乘数
* @return 累乘后的本货币对象。
*/
public MoneyUtil multiplyBy(double val) {
this.cent = Math.round(this.cent * val);
return this;
}
/**
* @Title: multiply
* @Description: TODO(货币乘法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:14:15
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
* 本货币对象的值不变。如果相乘后的金额不能转换为整数分,使用缺省的取整模式
* DEFUALT_ROUNDING_MODE
进行取整。
* @param val 乘数
* @return 相乘后的结果。
*/
public MoneyUtil multiply(BigDecimal val) {
return multiply(val, DEFAULT_ROUNDING_MODE);
}
/**
* @Title: multiplyBy
* @Description: TODO(货币累乘。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:13:51
*
* 本货币对象金额乘以乘数,并返回本货币对象。
* 如果相乘后的金额不能转换为整数分,使用缺省的取整方式
* DEFUALT_ROUNDING_MODE
进行取整。
* @param val 乘数
* @return 累乘后的结果。
*/
public MoneyUtil multiplyBy(BigDecimal val) {
return multiplyBy(val, DEFAULT_ROUNDING_MODE);
}
/**
* @Title: multiply
* @Description: TODO(货币乘法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:13:24
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额乘以乘数。
* 本货币对象的值不变。如果相乘后的金额不能转换为整数分,使用指定的取整方式
* roundingMode
进行取整。
* @param val 乘数
* @param roundingMode 取整方式
* @return 相乘后的结果。
*/
public MoneyUtil multiply(BigDecimal val, int roundingMode) {
BigDecimal newCent = BigDecimal.valueOf(cent).multiply(val);
return newMoneyWithSameCurrency(rounding(newCent, roundingMode));
}
/**
* @Title: multiplyBy
* @Description: TODO(货币累乘。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:12:52
*
* 本货币对象金额乘以乘数,并返回本货币对象。
* 如果相乘后的金额不能转换为整数分,使用指定的取整方式
* roundingMode
进行取整。
* @param val 乘数
* @param roundingMode 取整方式
* @return 累乘后的结果。
*/
public MoneyUtil multiplyBy(BigDecimal val, int roundingMode) {
BigDecimal newCent = BigDecimal.valueOf(cent).multiply(val);
this.cent = rounding(newCent, roundingMode);
return this;
}
/**
* @Title: divide
* @Description: TODO(货币除法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:12:19
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
* 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用四舍五入方式取整。
* @param val 除数
* @return 相除后的结果。
*/
public MoneyUtil divide(double val) {
return newMoneyWithSameCurrency(Math.round(cent / val));
}
/**
* @Title: divideBy
* @Description: TODO(货币累除。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:10:02
*
* 本货币对象金额除以除数,并返回本货币对象。
* 如果相除后的金额不能转换为整数分,使用四舍五入方式取整。
* @param val 除数
* @return 累除后的结果。
*/
public MoneyUtil divideBy(double val) {
this.cent = Math.round(this.cent / val);
return this;
}
/**
* @Title: divide
* @Description: TODO(货币除法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:09:38
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
* 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用缺省的取整模式
* DEFAULT_ROUNDING_MODE
进行取整。
* @param val 除数
* @return 相除后的结果。
*/
public MoneyUtil divide(BigDecimal val) {
return divide(val, DEFAULT_ROUNDING_MODE);
}
/**
* @Title: divide
* @Description: TODO(货币除法。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:09:11
*
* 返回一个新的货币对象,币种与本货币对象相同,金额为本货币对象的金额除以除数。
* 本货币对象的值不变。如果相除后的金额不能转换为整数分,使用指定的取整模式
* roundingMode
进行取整。
* @param val 除数
* @param roundingMode 取整
* @return 相除后的结果。
*/
public MoneyUtil divide(BigDecimal val, int roundingMode) {
BigDecimal newCent = BigDecimal.valueOf(cent).divide(val, roundingMode);
return newMoneyWithSameCurrency(newCent.longValue());
}
/**
* @Title: divideBy
* @Description: TODO(货币累除。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:08:46
*
* 本货币对象金额除以除数,并返回本货币对象。
* 如果相除后的金额不能转换为整数分,使用缺省的取整模式
* DEFAULT_ROUNDING_MODE
进行取整。
* @param val 除数
* @return 累除后的结果。
*/
public MoneyUtil divideBy(BigDecimal val) {
return divideBy(val, DEFAULT_ROUNDING_MODE);
}
/**
* @Title: divideBy
* @Description: TODO(货币累除。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:07:42
*
* 本货币对象金额除以除数,并返回本货币对象。
* 如果相除后的金额不能转换为整数分,使用指定的取整模式
* roundingMode
进行取整。
* @param val 除数
* @param roundingMode
* @return 累除后的结果。
*/
public MoneyUtil divideBy(BigDecimal val, int roundingMode) {
BigDecimal newCent = BigDecimal.valueOf(cent).divide(val, roundingMode);
this.cent = newCent.longValue();
return this;
}
/**
* @Title: allocate
* @Description: TODO(货币分配。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:07:12
*
* 将本货币对象尽可能平均分配成targets
份。
* 如果不能平均分配尽,则将零头放到开始的若干份中。分配
* 运算能够确保不会丢失金额零头。
* @param targets 待分配的份数
* @return 货币对象数组,数组的长度与分配份数相同,数组元素从大到小排列,所有货币对象的金额最多只相差1分。
*/
public MoneyUtil[] allocate(int targets) {
MoneyUtil[] results = new MoneyUtil[targets];
MoneyUtil lowResult = newMoneyWithSameCurrency(cent / targets);
MoneyUtil highResult = newMoneyWithSameCurrency(lowResult.cent + 1);
int remainder = (int) cent % targets;
for (int i = 0; i < remainder; i++) {
results[i] = highResult;
}
for (int i = remainder; i < targets; i++) {
results[i] = lowResult;
}
return results;
}
/**
* @Title: allocate
* @Description: TODO(货币分配。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:06:33
*
* 将本货币对象按照规定的比例分配成若干份。分配所剩的零头
* 从第一份开始顺序分配。分配运算确保不会丢失金额零头。
* @param ratios 分配比例数组,每一个比例是一个长整型,代表相对于总数的相对数。
* @return 货币对象数组,数组的长度与分配比例数组的长度相同。
*/
public MoneyUtil[] allocate(long[] ratios) {
MoneyUtil[] results = new MoneyUtil[ratios.length];
long total = 0;
for (int i = 0; i < ratios.length; i++) {
total += ratios[i];
}
long remainder = cent;
for (int i = 0; i < results.length; i++) {
results[i] = newMoneyWithSameCurrency((cent * ratios[i]) / total);
remainder -= results[i].cent;
}
for (int i = 0; i < remainder; i++) {
results[i].cent++;
}
return results;
}
// 格式化方法 =================================================
/**
* 生成本对象的缺省字符串表示
*/
public String toString() {
return getAmount().toString();
}
// 内部方法 ===================================================
/**
* @Title: assertSameCurrencyAs
* @Description: TODO(断言本货币对象与另一货币对象是否具有相同的币种。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:05:22
*
* 如果本货币对象与另一货币对象具有相同的币种,则方法返回。
* 否则抛出运行时异常java.lang.IllegalArgumentException
。
* @param other 另一货币对象
* @exception IllegalArgumentException 如果本货币对象与另一货币对象币种不同。
*/
protected void assertSameCurrencyAs(MoneyUtil other) {
if (!currency.equals(other.currency)) {
throw new IllegalArgumentException("Money math currency mismatch.");
}
}
/**
* @Title: rounding
* @Description: TODO(对BigDecimal型的值按指定取整方式取整。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:05:01
* @param val 待取整的BigDecimal值
* @param roundingMode 取整方式
* @return 取整后的long型值
*/
protected long rounding(BigDecimal val, int roundingMode) {
return val.setScale(0, roundingMode).longValue();
}
/**
* @Title: newMoneyWithSameCurrency
* @Description: TODO(创建一个币种相同,具有指定金额的货币对象。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:04:35
* @param cent 金额,以分为单位
* @return 一个新建的币种相同,具有指定金额的货币对象
*/
protected MoneyUtil newMoneyWithSameCurrency(long cent) {
MoneyUtil money = new MoneyUtil(0, currency);
money.cent = cent;
return money;
}
// 调试方式 ==================================================
/**
* @Title: dump
* @Description: TODO(生成本对象内部变量的字符串表示,用于调试。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:04:20
* @return 本对象内部变量的字符串表示。
*/
public String dump() {
String lineSeparator = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer();
sb.append("cent = ").append(cent).append(lineSeparator);
sb.append("currency = ").append(currency);
return sb.toString();
}
/**
* @Title: setCent
* @Description: TODO(设置货币的分值。)
* @author [email protected] (苟志强)
* @date 2017-7-3 下午4:04:10
* @param l
*/
public void setCent(long l) {
cent = l;
}
}