金钱数字转换成中文数值

简介: 金钱数字转换成中文数值

金钱数字转换成中文数值


关于中文数值表示参考链接:

https://baike.baidu.com/item/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97/2921705?fr=aladdin

package top.simba1949;
import java.util.*;
/**
 * 最高支持:1京 减 0.01
 *
 * 设计思路:
 * 将字符串通过小数点分割为整数部分和小数部分(小数部分取2位)
 *
 * 整数部分处理思路:
 *      数字字符串从后往前数,每8位一个单元,千百十万千百十个+单位
 *      每个单元,第三位是万位,需要特殊处理,
 *          |->如果万前面存在数字,但是万位没有数值,需要添加上万,
 *          |->如果万前面没有数值同时万没有数值,不用添加
 *
 * 小数部分处理思路:
 *      判断是否是否存在
 *          |->存在,先取第一位小数位做角,然后判断长度是否大于2,
 *          |    |->不大于等于2,直接返回
 *          |    |->大于等于2再取第二位小数做分返回
 *          |->不存在,返回`整`
 * @author anthony
 * @date 2021/1/26
 */
public class MoneyUtils {
    private static final String NUMBER_ZERO_STR = "0";
    private static final String NUMBER_ONE_STR = "1";
    private static final String NUMBER_TWO_STR = "2";
    private static final String NUMBER_THREE_STR = "3";
    private static final String NUMBER_FOUR_STR = "4";
    private static final String NUMBER_FIVE_STR = "5";
    private static final String NUMBER_SIX_STR = "6";
    private static final String NUMBER_SEVEN_STR = "7";
    private static final String NUMBER_EIGHT_STR = "8";
    private static final String NUMBER_NINE_STR = "9";
    private static final String NUMBER_POINT_STR = ".";
    private static final String DELIMITER_DECIMAL_POINT = "\\.";
    private static final String DELIMITER_COMMA = ",";
    private static final String CN_NUMBER_ZERO_STR = "零";
    private static final String CN_NUMBER_ONE_STR = "壹";
    private static final String CN_NUMBER_TWO_STR = "贰";
    private static final String CN_NUMBER_THREE_STR = "叁";
    private static final String CN_NUMBER_FOUR_STR = "肆";
    private static final String CN_NUMBER_FIVE_STR = "伍";
    private static final String CN_NUMBER_SIX_STR = "陆";
    private static final String CN_NUMBER_SEVEN_STR = "柒";
    private static final String CN_NUMBER_EIGHT_STR = "捌";
    private static final String CN_NUMBER_NINE_STR = "玖";
    private static final String CN_NUMBER_TEN_STR = "拾";
    private static final String CN_NUMBER_HUNDRED_STR = "佰";
    private static final String CN_NUMBER_THOUSAND_STR = "仟";
    private static final String CN_NUMBER_TEN_THOUSAND_STR = "万";
    private static final String CN_NUMBER_BILLION_STR = "亿";
    private static final String CN_NUMBER_TRILLION_STR = "兆";
    private static final String RMB_UNIT_YUAN = "圆";
    private static final String RMB_UNIT_JIAO = "角";
    private static final String RMB_UNIT_FEN = "分";
    private static final String NO_POINT = "整";
    /**
     * 数值与中文数字映射关系
     */
    private static Map<String, String> numberMap = new HashMap<>(16);
    /**
     * 长度与单位映射关系
     */
    private static Map<Integer, String> unitMap = new HashMap<>(16);
    /**
     * 从后往前数,每8个为单位,获取单位数值,千,百,十,万,千,百,十,一
     */
    private static Map<Integer, String> unitMap4Digits = new HashMap<>(16);
    static {
        numberMap.put(NUMBER_ZERO_STR, CN_NUMBER_ZERO_STR);
        numberMap.put(NUMBER_ONE_STR, CN_NUMBER_ONE_STR);
        numberMap.put(NUMBER_TWO_STR, CN_NUMBER_TWO_STR);
        numberMap.put(NUMBER_THREE_STR, CN_NUMBER_THREE_STR);
        numberMap.put(NUMBER_FOUR_STR, CN_NUMBER_FOUR_STR);
        numberMap.put(NUMBER_FIVE_STR, CN_NUMBER_FIVE_STR);
        numberMap.put(NUMBER_SIX_STR, CN_NUMBER_SIX_STR);
        numberMap.put(NUMBER_SEVEN_STR, CN_NUMBER_SEVEN_STR);
        numberMap.put(NUMBER_EIGHT_STR, CN_NUMBER_EIGHT_STR);
        numberMap.put(NUMBER_NINE_STR, CN_NUMBER_NINE_STR);
    }
    static {
        unitMap4Digits.put(1, "");
        unitMap4Digits.put(2, CN_NUMBER_TEN_STR);
        unitMap4Digits.put(3, CN_NUMBER_HUNDRED_STR);
        unitMap4Digits.put(4, CN_NUMBER_THOUSAND_STR);
        unitMap4Digits.put(5, CN_NUMBER_TEN_THOUSAND_STR);
        unitMap4Digits.put(6, CN_NUMBER_TEN_STR);
        unitMap4Digits.put(7, CN_NUMBER_HUNDRED_STR);
        unitMap4Digits.put(8, CN_NUMBER_THOUSAND_STR);
    }
    static {
        // 圆
        unitMap.put(1, RMB_UNIT_YUAN);
        // 亿
        unitMap.put(2, CN_NUMBER_BILLION_STR);
        // 兆
        unitMap.put(3, CN_NUMBER_TRILLION_STR);
    }
    /**
     * 钱币
     * 数字转换成中文大写
     * 目前最大支持一兆
     * @return
     */
    public static String moneyNumber2CnNumber(String original){
        if (null == original || original.trim().isEmpty()){
            return "";
        }
        // beforePoint 表示整数部分,afterPoint表示小数部分
        String beforePoint, afterPoint= "";
        String originalTrim = original.replace(" ", "").trim();
        if (originalTrim.contains(NUMBER_POINT_STR)){
            // 存在小数点
            String[] split = originalTrim.split(DELIMITER_DECIMAL_POINT);
            beforePoint = split[0].trim();
            afterPoint = split[1].trim();
        }else {
            // 不存在小数点
            beforePoint = originalTrim;
        }
        return integerDealWith(beforePoint) + decimalDealWith(afterPoint);
    }
    /**
     * 整数部分处理方式
     * @param integer
     * @return
     */
    private static String integerDealWith(String integer){
        if (null == integer || integer.trim().isEmpty()){
            return "";
        }
        // 从后往前数,每8位添加一个分割符号,
        List<String> list = new ArrayList<>();
        char[] chars = integer.trim().toCharArray();
        int j = 1;
        for (int i = chars.length - 1; i >= 0; i--) {
            list.add(String.valueOf(chars[i]));
            if (j%8 == 0){
                list.add(DELIMITER_COMMA);
            }
            j++;
        }
        Collections.reverse(list);
        // 获取带有分割符`,`的字符串
        StringBuilder builder = new StringBuilder();
        list.forEach(builder::append);
        String str = builder.toString();
        // 去掉头部逗号
        if (str.startsWith(DELIMITER_COMMA)){
            str = str.replaceFirst(DELIMITER_COMMA, "");
        }
        // 每8位分割后处理
        StringBuilder resultBuilder = new StringBuilder();
        String[] split = str.split(DELIMITER_COMMA);
        int length = split.length;
        for (int i = 0; i < length; i++) {
            resultBuilder.append(integerDealWithCoreWithUnit(split[i], unitMap.get(length - i)));
        }
        return resultBuilder.toString();
    }
    /**
     * 数字按照 `千万百万十万,万千百十个` 排序
     * @param number
     * @param unit 最后的单位
     * @return
     */
    private static String integerDealWithCoreWithUnit(String number, String unit){
        if (null == number || number.trim().isEmpty() || null == unit){
            return "";
        }
        StringBuilder builder = new StringBuilder();
        switch (number.length()){
            case 7: number = "0" + number;break;
            case 6: number = "00" + number;break;
            case 5: number = "000" + number;break;
            case 4: number = "0000" + number;break;
            case 3: number = "00000" + number;break;
            case 2: number = "000000" + number;break;
            case 1: number = "0000000" + number;break;
        }
        int length = number.length();
        int j = length;
        for (int i = 0; i < length; i++) {
            String value = String.valueOf(number.charAt(i));
            if (!NUMBER_ZERO_STR.equals(value)){
                builder.append(numberMap.get(value)).append(unitMap4Digits.get(j));
            }else {
                // 8位数,第四位数没有值但是前面有值
                if (i == 3 && builder.length() > 0){
                    builder.append(CN_NUMBER_TEN_THOUSAND_STR);
                }
            }
            j--;
        }
        // 添加最后的单位
        if (builder.length() > 0){
            builder.append(unit);
        }
        return builder.toString();
    }
    /**
     * 小数部分处理方式
     * @param decimal
     * @return
     */
    private static String decimalDealWith(String decimal){
        if (null == decimal || decimal.trim().isEmpty()){
            return NO_POINT;
        }
        // 自取两位小数
        StringBuilder builder = new StringBuilder();
        // 角
        String decimalTrim = decimal.trim();
        String tenthsNumberStr = String.valueOf(decimalTrim.charAt(0));
        if (!NUMBER_ZERO_STR.equals(tenthsNumberStr)){
            builder.append(numberMap.get(tenthsNumberStr)).append(RMB_UNIT_JIAO);
        }
        // 分
        if (decimalTrim.length() >= 2){
            String percentileNumberStr = String.valueOf(decimalTrim.charAt(1));
            if (!NUMBER_ZERO_STR.equals(percentileNumberStr)){
                builder.append(numberMap.get(percentileNumberStr)).append(RMB_UNIT_FEN);
            }
        }
        return builder.toString();
    }
    private MoneyUtils() {
    }
}


目录
相关文章
|
3月前
|
SQL 安全 前端开发
如何开发一套EHS健康安全环境管理系统中的绩效管理板块?(附架构图+流程图+代码参考)
本文探讨了如何将EHS(环境、健康与安全)工作转化为可量化、可持续改进的绩效管理体系。许多企业将EHS视为被动合规任务,但通过绩效管理,可将其升级为驱动企业长期价值的工具。文章详细介绍了EHS绩效管理的核心模块、系统架构设计、数据模型、评分算法、前端展示、开发技巧及落地建议,涵盖了从业务流程设计到技术实现的完整路径。同时,还提供了业务指标定义、规则引擎配置、数据采集与分析、可视化看板展示等内容,并结合示例代码与架构图,帮助开发者与管理者理解如何构建一个闭环的EHS绩效管理系统。
|
3月前
|
NoSQL 前端开发 JavaScript
用PHP实现持续监听Redis订阅并将消息推送至前端的技术
通过上述步骤,你可以构建一个服务器端PHP脚本持续监听Redis订阅,并利用WebSocket服务器将消息实时推送到前端的流程。这种机制适用于聊天应用程序、实时通知系统以及任何需要即时数据更新的场景。
144 0
|
6月前
|
JSON 前端开发 JavaScript
借助 CodeBuddy,我见证了一款在线代码格式化神器的诞生
借助 CodeBuddy,我见证了一款在线代码格式化神器的诞生
181 13
|
10月前
|
机器学习/深度学习 人工智能 物联网
TransPixar AI
TransPixar是由Adobe研究院与香港科技大学合作开发的AI系统,专注于文本到视频生成,特别擅长处理透明效果。它能生成包含Alpha通道的RGBA视频,使烟雾、反射等元素自然融入场景。采用扩散变换器架构和低秩适应微调方法,确保RGB和Alpha通道的一致性。该技术简化了视觉特效制作流程,降低了成本,并在娱乐、广告等领域有广泛应用前景。在线体验demo:[TransPixar](https://transpixar-ai.net/)。
|
11月前
|
人工智能 搜索推荐 API
自学记录鸿蒙API 13:实现人脸比对Core Vision Face Comparator
在完成文本识别和人脸检测项目后,我深入学习了HarmonyOS Next API 13中的Core Vision Face Comparator API,开发了一个简单的人脸比对工具。该API能进行高精度人脸比对并给出相似度评分,应用场景广泛,如照片分类、身份认证、个性化服务等。通过初始化服务、加载图片、实现比对功能和构建用户界面,最终实现了可靠的人脸比对功能。未来计划将此技术应用于更复杂的场景,如照片管理和个性化服务,并探索与其他AI能力的结合。如果你也对人脸比对感兴趣,不妨从简单的比对功能开始,逐步实现自己的创意!
315 61
|
11月前
|
人工智能 自然语言处理 并行计算
Maya:基于 LLaVA 开发的多模态小模型,能理解和处理八种语言,适用于低资源环境
Maya 是一个开源的多语言多模态模型,能够处理和理解八种不同语言,包括中文、法语、西班牙语、俄语、印地语、日语、阿拉伯语和英语。该模型基于LLaVA框架,通过指令微调和多语言数据集的预训练,提升了在视觉-语言任务中的表现,特别适用于低资源语言的内容生成和跨文化理解。
456 16
Maya:基于 LLaVA 开发的多模态小模型,能理解和处理八种语言,适用于低资源环境
|
11月前
|
机器学习/深度学习 人工智能 算法
《非计算机专业者:Python 开启人工智能职业新航道》
在人工智能蓬勃发展的今天,Python 作为其得力助手,凭借简洁语法和丰富库,成为非计算机专业人员适应时代、拓展职业的关键。学习 Python 需明确目标,夯实基础,掌握 NumPy、Pandas 等库的应用,并通过项目实战积累经验。持续学习与交流,紧跟技术动态,助力职业发展,在人工智能时代乘风破浪。
254 22
|
11月前
|
存储 运维 安全
《VERICUT 9.X电脑配置要求与安装说明(官方)》—— PDF文档
本文档详细介绍了 CGTech Vericut 9.X 的安装指南,涵盖安装前准备、安装流程、系统要求、故障排除、许可证配置及多种接口配置等内容,为用户提供全面的软件安装与配置指导。
507 3
|
12月前
|
存储 缓存 算法
RAID 的镜像是一种冗余技术
镜像是冗余技术的一种,通过在不同磁盘上创建数据的完整副本,提供数据保护。这种方法无需额外计算和校验,故障恢复迅速,支持并发读取,提高读I/O性能,但写入性能受影响。镜像技术虽提供高数据安全性,却需双倍存储空间,成本较高,适用于关键数据保护。此外,镜像可通过“拆分”实现几乎零备份窗口的数据备份。
330 4
|
存储 安全 物联网
计算机网络的类型
本文介绍了网络的分类,涵盖按覆盖范围(PAN、LAN、MAN、WAN)、使用场景(公网、外网、内网)、传输介质(有线、无线)、特殊类型(VLAN、SAN、网络桥接、接入网)及拓扑结构(总线型、星型、树型、环型、网状型)和交换方式(电路交换、报文交换、分组交换)等,详细阐述了各类网络的特点和技术。
1037 2