这个似乎是一道某公司的招聘试题。事实上还很实用,我一时心血来潮,到网上找了一个实现方法,然后还自己写了另一个方法。现整理摘抄如下。(暂时没时间作详细注释和进一步验证,请见谅)
package
org.jvk.util;
import
java.math.BigDecimal;
import
java.util.HashMap;
import
java.util.Map;
public
class
BigAmount {
public
final
static
Map<Character, String>
digit
=
new
HashMap<Character, String>(
10);
private
final
static
char
digitZero
=
'0'
;
private
final
static
char
bigZero
=
'
零
'
;
static
{
digit
.put(
'0'
,
"
零
"
);
digit
.put(
'1'
,
"
壹
"
);
digit
.put(
'2'
,
"
贰
"
);
digit
.put(
'3'
,
"
叁
"
);
digit
.put(
'4'
,
"
肆
"
);
digit
.put(
'5'
,
"
伍
"
);
digit
.put(
'6'
,
"
陆
"
);
digit
.put(
'7'
,
"
柒
"
);
digit
.put(
'8'
,
"
捌
"
);
digit
.put(
'9'
,
"
玖
"
);
}
final
BigDecimal
bigDecimal
;
public
BigAmount(BigDecimal bigDecimal) {
this
.
bigDecimal
= bigDecimal;
}
public
BigAmount(String bigDecimal) {
this
.
bigDecimal
=
new
BigDecimal(bigDecimal);
}
public
final
static
String[]
unit
= {
""
,
"
拾
"
,
"
佰
"
,
"
仟
"
,
"
万
"
};
//
十进制单位
,
亿属于另类
/**
*
自己写的方法
,
目前只能接受最大值为
9,999,999,999,999.99
的金额数
*
@param
bigDecimal
*
@return
大写金额
*/
public
static
String toBigAmount(BigDecimal bigDecimal) {
String money = bigDecimal.toPlainString();
String fraction =
""
;
//
小数部分
int
x = money.indexOf(
'.'
);
if
(x > 0) {
String fractionTemp = money.substring(x + 1);
if
(fractionTemp.length() > 1 && !fractionTemp.startsWith(
"00"
)) {
fraction =
digit
.get(fractionTemp.charAt(0)) +
"
角
"
+
digit
.get(fractionTemp.charAt(1)) +
"
分
"
;
}
else
if
(fractionTemp.charAt(0) !=
'0'
) {
fraction =
digit
.get(fractionTemp.charAt(0)) +
"
角
"
;
}
money = money.substring(0, x);
}
if
(money.charAt(0) ==
digitZero
)
return
fraction;
String result =
""
;
int
len = money.length();
String temp =
null
;
if
(len < 5) {
result = convertToBigAmount(money,
true
);
}
else
if
(len < 9) {
temp = convertToBigAmount(money.substring(0, len - 4),
true
);
result += temp +
"
万
"
;
result += convertToBigAmount(money.substring(len - 4),
false
);
}
else
if
(len < 14) {
temp = convertToBigAmount(money.substring(0, len - 8),
true
);
if
(temp.charAt(temp.length() - 1) ==
'
零
'
)
temp = temp.substring(0, temp.length() - 1);
result = temp +
"
亿
"
;
temp = convertToBigAmount(money.substring(len - 8, len - 4),
false
);
if
(temp.equals(
"
零
"
))
temp =
""
;
else
if
(temp.charAt(temp.length() - 1) ==
'
零
'
)
temp = temp.substring(0, temp.length() - 1);
if
(temp.length() > 0)
result += temp +
"
万
"
;
result += convertToBigAmount(money.substring(money.length() - 4),
false
);
}
else
{
return
"
金额数太大了
"
;
}
if
(result.charAt(result.length() - 1) ==
bigZero
)
return
result.substring(0, result.length() - 1) +
"
圆
"
+ (fraction.length() > 0 ? fraction :
"
整
"
);
return
result +
"
圆
"
+ (fraction.length() > 0 ? fraction :
"
整
"
);
}
/**
*
@param
money
*
@param
isHBit
*
@return
万以下的大写金额
*/
private
static
String convertToBigAmount(String money,
boolean
isHBit) {
int
len = money.length();
StringBuffer result =
new
StringBuffer(16);
for
(
int
i = 0; i < len; i++) {
if
(money.charAt(i) !=
'0'
) {
result.append(
digit
.get(money.charAt(i)) +
unit
[len - 1 - i]);
}
else
{
if
((!isHBit && result.length() == 0) || result.length() != len
&& result.charAt(result.length() - 1) !=
bigZero
)
result.append(
bigZero
);
}
}
return
result.toString();
}
/**
*
网上找的算法
,
目前没完全弄懂
*
*
@param
value
*
@return
大写金额
*/
public
static
String toBigAmount(
double
value) {
char
[] hunit = {
'
拾
'
,
'
佰
'
,
'
仟
'
};
//
段内位置表示
char
[] vunit = {
'
万
'
,
'
亿
'
};
//
段名表示
char
[] digit = {
'
零
'
,
'
壹
'
,
'
贰
'
,
'
叁
'
,
'
肆
'
,
'
伍
'
,
'
陆
'
,
'
柒
'
,
'
捌
'
,
'
玖
'
};
//
数字表示
long
midVal = (
long
) (value * 100);
//
转化成整形
String valStr = String.valueOf(midVal);
//
转化成字符串
String head = valStr.substring(0, valStr.length() - 2);
//
取整数部分
String rail = valStr.substring(valStr.length() - 2);
//
取小数部分
String prefix =
""
;
//
整数部分转化的结果
String suffix =
""
;
//
小数部分转化的结果
//
处理小数点后面的数
if
(rail.equals(
"00"
)) {
//
如果小数部分为
0
suffix =
"
整
"
;
}
else
{
suffix = digit[rail.charAt(0) -
'0'
] +
"
角
"
+ digit[rail.charAt(1) -
'0'
] +
"
分
"
;
//
否则把角分转化出来
}
//
处理小数点前面的数
char
[] chDig = head.toCharArray();
//
把整数部分转化成字符数组
char
zero =
'0'
;
//
标志
'0'
表示出现过
0
byte
zeroSerNum = 0;
//
连续出现
0
的次数
for
(
int
i = 0; i < chDig.
length
; i++) {
//
循环处理每个数字
int
idx = (chDig.
length
- i - 1) % 4;
//
取段内位置
int
vidx = (chDig.
length
- i - 1) / 4;
//
取段位置
if
(chDig[i] ==
'0'
) {
//
如果当前字符是
0
zeroSerNum++;
//
连续
0
次数递增
if
(zero ==
'0'
) {
//
标志
zero = digit[0];
}
else
if
(idx == 0 && vidx > 0 && zeroSerNum < 4) {
prefix += vunit[vidx - 1];
zero =
'0'
;
}
continue
;
}
zeroSerNum = 0;
//
连续
0
次数清零
if
(zero !=
'0'
) {
//
如果标志不为
0,
则加上
,
例如万
,
亿什么的
prefix += zero;
zero =
'0'
;
}
prefix += digit[chDig[i] -
'0'
];
//
转化该数字表示
if
(idx > 0)
prefix += hunit[idx - 1];
if
(idx == 0 && vidx > 0) {
prefix += vunit[vidx - 1];
//
段结束位置应该加上段名如万
,
亿
}
}
if
(prefix.length() > 0)
prefix +=
'
圆
'
;
//
如果整数部分存在
,
则有圆的字样
return
prefix + suffix;
}
public
String toString() {
return
toBigAmount(
bigDecimal
);
// return toBigAmount(bigDecimal.floatValue());
}
}