JAVA数字转中文大写两种实现代码

 更新时间:2025年07月02日 08:58:28   作者:叩叮ING  
在Java程序实现数字金额转为大写中文金额,是一项非常常见的编程任务,这篇文章主要介绍了JAVA数字转中文大写两种实现方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下,

一般在收据打印过程中,可能会要求展示中文大写金额,以下提供两种实现。

1正常代码逻辑处理

优点:易理解,好维护

缺点:代码较长

package com.test;

import java.math.BigDecimal;

public class NumberToChinese {
    private static final String[] NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    private static final String[] UNITS = {"", "拾", "佰", "仟"};
    private static final String[] BIG_UNITS = {"", "万", "亿", "兆"};

    public static String numberToChinese(double number) {
        boolean isNegative = number < 0;
        number = Math.abs(number);

        BigDecimal bigDecimal = new BigDecimal(String.valueOf(number));
        long integerPart = bigDecimal.longValue();
        int decimalPart = (bigDecimal.subtract(new BigDecimal(integerPart)).multiply(new BigDecimal(100))).intValue();

        if (integerPart == 0 && decimalPart == 0) {
            return isNegative ? "负零元整" : "零元整";
        }

        StringBuilder result = new StringBuilder();
        int unitIndex = 0;
        boolean zeroFlag = false;
        while (integerPart > 0) {
            long group = integerPart % 10000;
            if (group != 0) {
                if (zeroFlag) {
                    result.insert(0, "零");
                }
                result.insert(0, BIG_UNITS[unitIndex]);
                result.insert(0, groupToChinese(group));
                zeroFlag = false;
            } else {
                zeroFlag = true;
            }
            integerPart /= 10000;
            unitIndex++;
        }

        // 去除多余的零
        while (result.length() > 0 && result.charAt(0) == '零') {
            result.deleteCharAt(0);
        }

        // 如果小数部分为 0,直接添加“元整”
        if (decimalPart == 0) {
            // 避免出现“零元整”情况,这里判断结果最后是否是大单位,如果是直接加“整”
            if (result.length() > 0 && isBigUnit(result.charAt(result.length() - 1))) {
                result.append("整");
            } else if("零".equals(result.substring(result.length() - 1,result.length()))) {
                result.replace(result.length() - 1,result.length(),"").append("元整");
            }else{
                result.append("元整");
            }
        } else {
            result.append("元");
            String decimalStr = decimalToChinese(decimalPart);
            if (!decimalStr.isEmpty()) {
                result.append(decimalStr);
            }
        }


        if (isNegative) {
            result.insert(0, "负");
        }

        return result.toString();
    }

    private static String groupToChinese(long group) {
        StringBuilder groupResult = new StringBuilder();
        boolean zeroFlag = false;
        for (int i = 0; i < 4; i++) {
            int digit = (int) (group / (long) Math.pow(10, 3 - i) % 10);
            if (digit != 0) {
                if (zeroFlag) {
                    groupResult.append("零");
                }
                groupResult.append(NUMBERS[digit]).append(UNITS[3 - i]);
                zeroFlag = false;
            } else {
                zeroFlag = true;
            }
        }
        String result = groupResult.toString();
        if (result.endsWith("零")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    private static String decimalToChinese(int decimalPart) {
        StringBuilder decimalResult = new StringBuilder();
        int jiao = decimalPart / 10;
        int fen = decimalPart % 10;

        if (jiao != 0) {
            decimalResult.append(NUMBERS[jiao]).append("角");
        } else if (fen != 0) {
            decimalResult.append("零");
        }

        if (fen != 0) {
            decimalResult.append(NUMBERS[fen]).append("分");
        }

        return decimalResult.toString();
    }

    private static boolean isBigUnit(char c) {
        for (String unit : BIG_UNITS) {
            if (unit.length() > 0 && unit.charAt(0) == c) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        double positiveInteger = 510000.00;
        double positiveDecimal = 12345.67;
        double negativeInteger = -500000.00;
        double negativeDecimal = -12345.67;
        double zeroNumber = 0;
        double wan = 51111.00;

        String positiveIntegerChinese = numberToChinese(positiveInteger);
        String positiveDecimalChinese = numberToChinese(positiveDecimal);
        String negativeIntegerChinese = numberToChinese(negativeInteger);
        String negativeDecimalChinese = numberToChinese(negativeDecimal);
        String zeroChinese = numberToChinese(zeroNumber);
        String wanChinese = numberToChinese(wan);

        System.out.println("正整数金额转换结果: " + positiveIntegerChinese);
        System.out.println("正小数金额转换结果: " + positiveDecimalChinese);
        System.out.println("负整数金额转换结果: " + negativeIntegerChinese);
        System.out.println("负小数金额转换结果: " + negativeDecimalChinese);
        System.out.println("零金额转换结果: " + zeroChinese);
        System.out.println("wan转换结果: " + wanChinese);
    }
}

代码方法作用解释:

  • 常量定义

    • NUMBERS:存储中文数字大写字符。
    • UNITS:存储整数部分每四位一组内的单位(个、十、百、千)。
    • BIG_UNITS:存储整数部分每四位一组的大单位(万、亿、兆)。
    • DECIMAL_UNIT:存储小数部分的单位(角、分)。
  • numberToChinese 方法

    • 使用 BigDecimal 处理输入的数字,避免浮点数精度问题。
    • 分离整数部分和小数部分。
    • 处理整数部分,按每四位一组进行转换,并添加大单位。
    • 处理小数部分,根据小数位的值添加对应的中文大写和单位。
  • groupToChinese 方法

    • 将每四位一组的数字转换为中文大写。
    • 处理连续零的情况,避免出现多余的零。

2使用正则

优点:代码片段短

缺点:使用了正则的贪婪符号,可能会造成代码回溯情况,严重可造成阻断风险

关于正则常见贪婪字符,点击查看

public static String digitUppercase(double n){
        String[] fraction = {"角", "分"};
        String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
        String[][] unit = {
  
  {"元", "万", "亿"},
                {"", "拾", "佰", "仟"}};

        String head = n < 0? "负": "";
        n = Math.abs(n);

        String s = "";
        for (int i = 0; i < fraction.length; i++) {
            BigDecimal bd = BigDecimal.valueOf(n);
            bd = bd.setScale(2, bd.ROUND_HALF_EVEN);
            BigDecimal rs = bd.multiply(BigDecimal.valueOf(10)).multiply(BigDecimal.valueOf(Math.pow(10, i))).divideAndRemainder(new BigDecimal(10))[1];
            s+=(digit[(int)(Math.floor(rs.doubleValue()))]+ fraction[i]).replaceAll("(零.)+", "");
        }
        if(s.length()<1){
            s = "整";
        }
        int integerPart = (int)Math.floor(n);

        for (int i = 0; i < unit[0].length && integerPart > 0; i++) {
            String p ="";
            for (int j = 0; j < unit[1].length && n > 0; j++) {
                p = digit[integerPart%10]+unit[1][j] + p;
                integerPart = integerPart/10;
            }
            s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
        }
        return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
    }

总结 

到此这篇关于JAVA数字转中文大写两种实现代码的文章就介绍到这了,更多相关JAVA数字转中文大写内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring中Bean有关NullPointerException异常的原因分析

    Spring中Bean有关NullPointerException异常的原因分析

    在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerException,解决方法包括避免在静态方法中使用注入的bean,或者使用Spring的ApplicationContext来获取bean,但后者不推荐
    2024-12-12
  • Java全排列算法字典序下的下一个排列讲解

    Java全排列算法字典序下的下一个排列讲解

    今天小编就为大家分享一篇关于Java全排列字典序下的下一个排列,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • rocketmq如何修改存储路径

    rocketmq如何修改存储路径

    这篇文章主要介绍了rocketmq如何修改存储路径的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Win10 Java jdk14.0.2安装及环境变量配置详细教程

    Win10 Java jdk14.0.2安装及环境变量配置详细教程

    这篇文章主要介绍了Win10 Java jdk14.0.2安装及环境变量配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • 基于spring DI的三种注入方式分析

    基于spring DI的三种注入方式分析

    这篇文章主要介绍了基于spring DI的三种注入方式分析,具有很好的参考价值,希望对大家有所帮助。
    2021-07-07
  • Java 高并发七:并发设计模型详解

    Java 高并发七:并发设计模型详解

    本文主要介绍Java高并发 并发设计模型的知识,这里主要讲解 1. 什么是设计模式 2. 单例模式 3. 不变模式 4. Future模式 5. 生产者消费者,有需要的小伙伴可以参考下
    2016-09-09
  • java jpa如何自定义sql语句

    java jpa如何自定义sql语句

    这篇文章主要介绍了java jpa如何自定义sql语句方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 关于SpringMVC对Restful风格的支持详解

    关于SpringMVC对Restful风格的支持详解

    Restful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格,是对http协议的诠释,下面这篇文章主要给大家介绍了关于SpringMVC对Restful风格支持的相关资料,需要的朋友可以参考下
    2022-01-01
  • Spring MVC和springboot静态资源处理问题

    Spring MVC和springboot静态资源处理问题

    这篇文章主要介绍了Spring MVC和springboot静态资源处理问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • java枚举转list通用类过程

    java枚举转list通用类过程

    文章介绍了如何将Java枚举类型转换为List<Map<String, Object>>的通用类,该类可以实现枚举到列表的转换,并且示例了使用方法
    2025-03-03

最新评论