This commit is contained in:
Looly 2024-09-21 18:21:44 +08:00
parent 7ead9ec68d
commit f456cd5d2a
3 changed files with 41 additions and 45 deletions

View File

@ -746,7 +746,7 @@ public class CollUtil {
*/ */
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public static <T> Collection<T> create(final Class<?> collectionType, final Class<T> elementType) { public static <T> Collection<T> create(final Class<?> collectionType, final Class<T> elementType) {
if (collectionType.isAssignableFrom(EnumSet.class)) { if (EnumSet.class.isAssignableFrom(collectionType)) {
return (Collection<T>) EnumSet.noneOf((Class<Enum>) Assert.notNull(elementType)); return (Collection<T>) EnumSet.noneOf((Class<Enum>) Assert.notNull(elementType));
} }

View File

@ -83,7 +83,9 @@ public class ChineseNumberParser {
final int dotIndex = chinese.indexOf('点'); final int dotIndex = chinese.indexOf('点');
// 整数部分 // 整数部分
BigDecimal result = NumberUtil.toBigDecimal(parseLongFromChineseNumber(chinese, dotIndex > 0 ? dotIndex : chinese.length())); final char[] charArray = chinese.toCharArray();
BigDecimal result = NumberUtil.toBigDecimal(
parseLongFromChineseNumber(charArray, 0, dotIndex > 0 ? dotIndex : charArray.length));
// 小数部分 // 小数部分
if (dotIndex > 0) { if (dotIndex > 0) {
@ -91,7 +93,10 @@ public class ChineseNumberParser {
for (int i = dotIndex + 1; i < length; i++) { for (int i = dotIndex + 1; i < length; i++) {
// 保留位数取决于实际数字的位数 // 保留位数取决于实际数字的位数
// result + (numberChar / 10^(i-dotIndex)) // result + (numberChar / 10^(i-dotIndex))
result = result.add(NumberUtil.div(chineseToNumber(chinese.charAt(i)), BigDecimal.TEN.pow(i-dotIndex), (length - dotIndex + 1))); result = result.add(NumberUtil.div(
chineseToNumber(chinese.charAt(i)),
BigDecimal.TEN.pow(i-dotIndex), (length - dotIndex + 1)
));
} }
} }
@ -112,64 +117,53 @@ public class ChineseNumberParser {
return null; return null;
} }
int yi = chineseMoneyAmount.indexOf(""); final char[] charArray = chineseMoneyAmount.toCharArray();
if (yi == -1) { int yEnd = ArrayUtil.indexOf(charArray, '元');
yi = chineseMoneyAmount.indexOf(""); if (yEnd < 0) {
yEnd = ArrayUtil.indexOf(charArray, '圆');
} }
final int ji = chineseMoneyAmount.indexOf("");
final int fi = chineseMoneyAmount.indexOf("");
// 先找到单位为元的数字 // 先找到单位为元的数字
String yStr = null; long y = 0;
if (yi > 0) { if (yEnd > 0) {
yStr = chineseMoneyAmount.substring(0, yi); y = parseLongFromChineseNumber(charArray, 0, yEnd);
} }
// 再找到单位为角的数字 // 再找到单位为角的数字
String jStr = null; long j = 0;
if (ji > 0) { final int jEnd = ArrayUtil.indexOf(charArray, '角');
if (yi >= 0) { if (jEnd > 0) {
if (yEnd >= 0) {
//前面有元,角肯定要在元后面 //前面有元,角肯定要在元后面
if (ji > yi) { if (jEnd > yEnd) {
jStr = chineseMoneyAmount.substring(yi + 1, ji); j = parseLongFromChineseNumber(charArray, yEnd + 1, jEnd);
} }
} else { } else {
//没有元只有角 //没有元只有角
jStr = chineseMoneyAmount.substring(0, ji); j = parseLongFromChineseNumber(charArray, 0, jEnd);
} }
} }
// 再找到单位为分的数字 // 再找到单位为分的数字
String fStr = null; long f = 0;
if (fi > 0) { final int fEnd = ArrayUtil.indexOf(charArray, '分');
if (ji >= 0) { if (fEnd > 0) {
if (jEnd >= 0) {
//有角分肯定在角后面 //有角分肯定在角后面
if (fi > ji) { if (fEnd > jEnd) {
fStr = chineseMoneyAmount.substring(ji + 1, fi); f = parseLongFromChineseNumber(charArray, jEnd + 1, fEnd);
} }
} else if (yi > 0) { } else if (yEnd > 0) {
//没有角有元那就坐元后面找 //没有角有元元后面找
if (fi > yi) { if (fEnd > yEnd) {
fStr = chineseMoneyAmount.substring(yi + 1, fi); f = parseLongFromChineseNumber(charArray, yEnd + 1, fEnd);
} }
} else { } else {
//没有元只有分 //没有元只有分
fStr = chineseMoneyAmount.substring(0, fi); f = parseLongFromChineseNumber(charArray, 0, fEnd);
} }
} }
//
long y = 0, j = 0, f = 0;
if (StrUtil.isNotBlank(yStr)) {
y = parseLongFromChineseNumber(yStr, yStr.length());
}
if (StrUtil.isNotBlank(jStr)) {
j = parseLongFromChineseNumber(jStr, jStr.length());
}
if (StrUtil.isNotBlank(fStr)) {
f = parseLongFromChineseNumber(fStr, fStr.length());
}
BigDecimal amount = new BigDecimal(y); BigDecimal amount = new BigDecimal(y);
amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN, 2, RoundingMode.HALF_UP)); amount = amount.add(BigDecimal.valueOf(j).divide(BigDecimal.TEN, 2, RoundingMode.HALF_UP));
amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); amount = amount.add(BigDecimal.valueOf(f).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
@ -184,10 +178,11 @@ public class ChineseNumberParser {
* </ul> * </ul>
* *
* @param chinese 中文字符 * @param chinese 中文字符
* @param beginIndex 起始位置
* @param toIndex 结束位置不包括如果提供的是整数这个为length()小数则是的位置 * @param toIndex 结束位置不包括如果提供的是整数这个为length()小数则是的位置
* @return 数字 * @return 数字
*/ */
public static long parseLongFromChineseNumber(final String chinese, final int toIndex) { public static long parseLongFromChineseNumber(final char[] chinese, final int beginIndex, final int toIndex) {
long result = 0; long result = 0;
// 节总和 // 节总和
@ -195,8 +190,8 @@ public class ChineseNumberParser {
long number = 0; long number = 0;
ChineseUnit unit = null; ChineseUnit unit = null;
char c; char c;
for (int i = 0; i < toIndex; i++) { for (int i = beginIndex; i < toIndex; i++) {
c = chinese.charAt(i); c = chinese[i];
final int num = chineseToNumber(c); final int num = chineseToNumber(c);
if (num >= 0) { if (num >= 0) {
if (num == 0) { if (num == 0) {
@ -207,7 +202,7 @@ public class ChineseNumberParser {
unit = null; unit = null;
} else if (number > 0) { } else if (number > 0) {
// 多个数字同时出现报错 // 多个数字同时出现报错
throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese.charAt(i - 1), c, i)); throw new IllegalArgumentException(StrUtil.format("Bad number '{}{}' at: {}", chinese[i - 1], c, i));
} }
// 普通数字 // 普通数字
number = num; number = num;

View File

@ -73,8 +73,9 @@ public class RomanNumberFormatter {
int prevValue = 0; int prevValue = 0;
int currValue; int currValue;
for (int i = roman.length() - 1; i >= 0; i--) { final char[] charArray = roman.toCharArray();
final char c = roman.charAt(i); for (int i = charArray.length - 1; i >= 0; i--) {
final char c = charArray[i];
switch (c) { switch (c) {
case 'I': case 'I':
currValue = 1; currValue = 1;