java阿拉伯数字转中文或金钱

前言:

网上很多算法都是到亿就gg了,目前的算法能到大数,什么是大数?来张图了解下

算法可以到1000大数,也就是10的75次方,不过一般京以上是用不到了

有个细节,105000是读十万五千,还是十万零五千,网上查了一些资料,还是读十万零五千的规范一些

演示

示例一:普通转换

System.out.println(NumberUtil.numberToChinese("1024"));

结果:

示例二:大数字转换

Integer.MAX_VALUE都不想演示了,直接Long.MAX_VALUE

System.out.println(NumberUtil.numberToChinese(Long.MAX_VALUE));

结果:

示例三:转换金钱

System.out.println(NumberUtil.numberToMoney("105000"));

 结果:

示例4:转换有小数的金钱

注意:最多只能有2位小数点

System.out.println(NumberUtil.numberToMoney("0.61"));
System.out.println(NumberUtil.numberToMoney("1024.00"));
System.out.println(NumberUtil.numberToMoney(1024.06));

结果:

 代码

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 数字转换工具
 *
 * @author 猴哥
 */
public class NumberUtil {
	/**
	 * 数字转中文
	 *
	 * @param number 数字
	 * @return 中文
	 */
	public static String numberToChinese(String number) {
		return numberToChinese(number, false);
	}

	/**
	 * 数字转中文
	 *
	 * @param number 数字
	 * @return 中文
	 */
	public static String numberToChinese(long number) {
		return numberToChinese(String.valueOf(number));
	}

	/**
	 * 数字转中文
	 *
	 * @param number 数字
	 * @return 中文
	 */
	public static String numberToChinese(int number) {
		return numberToChinese(String.valueOf(number));
	}

	/**
	 * 数字转中文
	 *
	 * @param number 数字
	 * @return 中文
	 */
	public static String numberToChinese(BigInteger number) {
		return numberToChinese(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(String number) {
		return numberToChinese(number, true);
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(float number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(double number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(int number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(long number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(BigInteger number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转金钱
	 *
	 * @param number 数字
	 * @return 金钱
	 */
	public static String numberToMoney(BigDecimal number) {
		return numberToMoney(String.valueOf(number));
	}

	/**
	 * 数字转中文
	 *
	 * @param number 数字
	 * @param money 是否是金钱模式
	 * @return 中文
	 */
	private static String numberToChinese(String number, boolean money) {
		// 单位
		final List<String> units = Arrays.asList("万", "亿", "兆", "京", "垓", "杼", "穰", "沟", "涧", "正", "载", "极",
				"恒河沙", "阿僧祇", "那由它", "不可思议", "无量", "大数");
		// 数字转中文
		List<String> chineseList = Arrays.asList("", "一", "二", "三", "四", "五", "六", "七", "八", "九");
		// 位数单位
		List<String> digitList = Arrays.asList("", "十", "百", "千");

		// 字符串校验
		Optional.ofNullable(number).orElseThrow(() -> new RuntimeException("内容不能为空"));

		// 如果是金钱模式
		if (money) {
			chineseList = Arrays.asList("", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");
			digitList = Arrays.asList("", "拾", "佰", "仟");

			// 校验金钱
			if (!number.matches("^\\d+(.\\d{1,2})?$")) {
				throw new RuntimeException("不符合金钱格式");
			}
		} else if (!number.matches("^\\d+$")) {
			throw new RuntimeException("请输入自然数");
		}

		// 封装对象(每个字符给它一个对象)
		List<ChineseChar> chineseChars = new LinkedList<>();
		// 小数部分
		LinkedList<ChineseChar> decimals = new LinkedList<>();
		boolean isDecimal = false;
		char[] charArray = number.toCharArray();
		for (int i = 0; i < charArray.length; i++) {
			// 如果遇到小数点
			if (charArray[i] == '.') {
				isDecimal = true;
				continue;
			}

			ChineseChar chineseChar = new ChineseChar();
			// 数字
			chineseChar.setNumber(Integer.parseInt(charArray[i] + ""));
			// 中文字符
			chineseChar.setChinese(chineseList.get(chineseChar.getNumber()));
			// 从右往左第几位
			chineseChar.setDigit(charArray.length - i);
			// 单位
			chineseChar.setDigitName(digitList.get((chineseChar.getDigit() + 3) % 4));

			// 如果是小数
			if (isDecimal) {
				// 添加到小数位
				decimals.add(chineseChar);
			} else {
				chineseChars.add(chineseChar);
			}
		}

		// 金钱模式如果有小数位,需要重新计算位数
		if (money && isDecimal) {
			for (int i = 0; i < chineseChars.size(); i++) {
				ChineseChar chineseChar = chineseChars.get(i);
				chineseChar.setDigit(chineseChars.size() - i);
				chineseChar.setDigitName(digitList.get((chineseChar.getDigit() + 3) % 4));
			}
		}

		for (int i = 0; i < chineseChars.size(); i++) {
			ChineseChar chineseChar = chineseChars.get(i);

			// 常规
			chineseChar.setResult(chineseChar.getChinese() + chineseChar.getDigitName());

			// 处理为0的数字
			if (chineseChar.getNumber() == 0) {
				chineseChar.setResult("");
			}

			// 处理十位、十万位、十亿位等等
			if (chineseChar.getDigit() % 4 == 2) {
				if (chineseChar.getNumber() == 1 && chineseChars.size() == chineseChar.getDigit()) {
					chineseChar.setResult(chineseChar.getDigitName());
				}
			}
		}

		// 补零
		for (int i = chineseChars.size() - 1; i >= 0; i--) {
			ChineseChar chineseChar = chineseChars.get(i);
			// 如果遇到0
			if (chineseChar.getNumber() == 0) {
				chineseChar.setResult("零");
				// 前面的零全部忽略
				for (int j = i - 1; j >= 0 && chineseChars.get(j).getNumber() == 0; j--) {
					i = j;
				}
			}
		}

		// 去掉结尾的零
		for (int i = chineseChars.size() - 1; i >= 0 && chineseChars.get(i).getNumber() == 0; i--) {
			chineseChars.get(i).setResult("");
		}

		// 遍历每个字符,加上计量单位
		for (int i = 0; i < chineseChars.size(); i++) {
			ChineseChar chineseChar = chineseChars.get(i);
			// 遍历计量单位
			for (int j = 0; j < units.size(); j++) {
				String unit = units.get(j);
				// 如果当前的位数刚好是计量单位的位数
				if (chineseChar.getDigit() == (j + 1) * 4 + 1) {
					// 如果是前4位,则加上单位
					// 如果这块区域有值,也加上单位
					if (i < 4
							|| chineseChars.get(i - 1).getNumber() != 0
							|| chineseChars.get(i - 2).getNumber() != 0
							|| chineseChars.get(i - 3).getNumber() != 0) {
						// 把计量单位加上去
						chineseChar.setResult(chineseChar.getNumber() == 0 ? unit + chineseChar.getResult() : chineseChar.getResult() + unit);
					}
					break;
				}
			}
		}

		String result = chineseChars.stream()
				.map(ChineseChar::getResult)
				.collect(Collectors.joining(""));

		// 判断是否为0
		result = zero(result, chineseChars);

		// 如果是金钱
		if (money) {
			return moneyHandler(result, decimals);
		}

		return result;
	}

	/**
	 * 判断是否为零
	 *
	 * @param result 结果
	 * @param chineseChars 中文
	 * @return 中文
	 */
	private static String zero(String result, List<ChineseChar> chineseChars) {
		boolean isZero = chineseChars.stream().allMatch(chineseChar -> chineseChar.getNumber() == 0);
		return isZero ? "零" : result;
	}

	/**
	 * 处理金钱的小数部分
	 *
	 * @param result 整数处理结果
	 * @param decimals 金钱小数位
	 * @return 处理结果
	 */
	private static String moneyHandler(String result, LinkedList<ChineseChar> decimals) {
		result += "元";

		// 如果没有小数位
		if (decimals.isEmpty()) {
			result += "整";
			return result;
		}

		// 处理角
		ChineseChar jiao = decimals.pop();
		result += jiao.getNumber() == 0 ? "" : jiao.getChinese() + "角";

		// 处理分
		ChineseChar fen = null;
		if (!decimals.isEmpty() && (fen = decimals.removeFirst()) != null && fen.getNumber() != 0) {
			result += jiao.getNumber() == 0 ? "零" + fen.getChinese() + "分" : fen.getChinese() + "分";
		}

		// 如果是.0或者.00
		if (jiao.getNumber() == 0 && (fen == null || fen.getNumber() == 0)) {
			result += "整";
		}

		return result;
	}

	/**
	 * 字符对象
	 */
	static class ChineseChar {
		/**
		 * 数字
		 */
		private Integer number;

		/**
		 * 中文
		 */
		private String chinese;

		/**
		 * 位数
		 */
		private Integer digit;

		/**
		 * 位数名称
		 */
		private String digitName;

		/**
		 * 结果
		 */
		private String result;

		public String getChinese() {
			return chinese;
		}

		public void setChinese(String chinese) {
			this.chinese = chinese;
		}

		public Integer getNumber() {
			return number;
		}

		public void setNumber(Integer number) {
			this.number = number;
		}

		public Integer getDigit() {
			return digit;
		}

		public void setDigit(Integer digit) {
			this.digit = digit;
		}

		public String getDigitName() {
			return digitName;
		}

		public void setDigitName(String digitName) {
			this.digitName = digitName;
		}

		public String getResult() {
			return result;
		}

		public void setResult(String result) {
			this.result = result;
		}

		@Override
		public String toString() {
			return "ChineseChar{" +
					"number=" + number +
					", chinese='" + chinese + '\'' +
					", digit=" + digit +
					", digitName='" + digitName + '\'' +
					", result='" + result + '\'' +
					'}';
		}
	}
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值