Java常用数字工具类 数字转汉字(1)

 更新时间:2017年05月09日 16:25:09   作者:龙轩  
这篇文章主要为大家详细介绍了Java常用数字工具类,数字转汉字,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本人是从事互联网金融行业的,所以会接触到一些金融类的问题,常见的一种就是数字转汉字大小写的问题。所以抽空就写了一个小小的工具类,实现了数字转汉字、大数相加、相减、相乘的工具类,希望能帮助有需求的同行们。本篇就分享一下数字转化为汉字的思路吧。

数字转汉字的原理:

  • 拆分:由于整数部分要加权值,而小数部分直接转换即可,所以首先要将数字拆分成整数+小数;
  • 整数处理:按照我们的中国人的习惯,把数字格式化成4位一组,不足4位前面补0。每次处理4位,按位匹配数组中的汉字+权值。即按照数值找数字数组(num_lower 、num_upper )中对应位置的汉字,按照在4位中的偏移量在单位权值数组(unit_lower 、unit_upper )中找。比如21,转化4位为0021,前面的0不用管,2对应数字“二”,权值是“十”,1对应数字“一”,权值是“(个)”用空字符串代替。即得到“二十一”。每4位处理完后,还要整体对应一个权值,比如“万、亿、兆”等;
  • 小数处理:小数部分直接按位对应汉字数组和权值即可。

废话了这么多,可能云里雾里的,看看具体代码吧:

//num 表示数字,lower表示小写,upper表示大写 
private static final String[] num_lower = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; 
private static final String[] num_upper = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; 
 
//unit 表示单位权值,lower表示小写,upper表示大写 
private static final String[] unit_lower = { "", "十", "百", "千" }; 
private static final String[] unit_upper = { "", "拾", "佰", "仟"}; 
private static final String[] unit_common = {"","万", "亿","兆","京","垓","秭","穰","沟","涧","正","载"}; 
 
//允许的格式 
private static final List<String> promissTypes = Arrays.asList("INTEGER","INT","LONG","DECIMAL","FLOAT","DOUBLE","STRING","BYTE","TYPE","SHORT"); 
 
/** 
 * 数字转化为小写的汉字 
 * 
 * @param num 将要转化的数字 
 * @return 
 */ 
public static String toChineseLower(Object num){ 
 return format(num, num_lower, unit_lower); 
} 
 
/** 
 * 数字转化为大写的汉字 
 * 
 * @param num 将要转化的数字 
 * @return 
 */ 
public static String toChineseUpper(Object num){ 
 return format(num, num_upper, unit_upper); 
} 
 
/** 
 * 格式化数字 
 * 
 * @param num 原数字 
 * @param numArray 数字大小写数组 
 * @param unit 单位权值 
 * @return 
 */ 
private static String format(Object num,String[] numArray,String[] unit){ 
 if(!promissTypes.contains(num.getClass().getSimpleName().toUpperCase())){ 
 throw new RuntimeException("不支持的格式类型"); 
 } 
 //获取整数部分 
 String intnum = getInt(String.valueOf(num)); 
 //获取小数部分 
 String decimal = getFraction(String.valueOf(num)); 
 //格式化整数部分 
 String result = formatIntPart(intnum,numArray,unit); 
 if(!"".equals(decimal)){//小数部分不为空 
 //格式化小数 
 result += "点"+formatFractionalPart(decimal, numArray); 
 } 
 return result; 
} 
 
/** 
 * 格式化整数部分 
 * 
 * @param num 整数部分 
 * @param numArray 数字大小写数组 
 * @return 
 */ 
private static String formatIntPart(String num,String[] numArray,String[] unit){ 
 
 //按4位分割成不同的组(不足四位的前面补0) 
 Integer[] intnums = split2IntArray(num); 
 
 boolean zero = false; 
 StringBuffer sb = new StringBuffer(); 
 for(int i=0;i<intnums.length;i++){ 
 //格式化当前4位 
 String r = formatInt(intnums[i], numArray,unit); 
 if("".equals(r)){// 
 if((i+1)==intnums.length){ 
 sb.append(numArray[0]);//结果中追加“零” 
 }else{ 
 zero=true; 
 } 
 }else{//当前4位格式化结果不为空(即不为0) 
 if(zero || (i>0 && intnums[i]<1000)){//如果前4位为0,当前4位不为0 
 sb.append(numArray[0]);//结果中追加“零” 
 } 
 sb.append(r); 
 sb.append(unit_common[intnums.length-1-i]);//在结果中添加权值 
 zero=false; 
 } 
 } 
 return sb.toString(); 
} 
 
/** 
 * 格式化小数部分 
 * 
 * @param decimal 小数部分 
 * @param numArray 数字大小写数组 
 * @return 
 */ 
private static String formatFractionalPart(String decimal,String[] numArray) { 
 char[] val = String.valueOf(decimal).toCharArray(); 
 int len = val.length; 
 StringBuilder sb = new StringBuilder(); 
 for (int i = 0; i < len; i++) { 
 int n = Integer.valueOf(val[i] + ""); 
 sb.append(numArray[n]); 
 } 
 return sb.toString(); 
} 
 

拆分整数和小数的方法在这里:

/** 
 * 获取整数部分 
 * 
 * @param num 
 * @return 
 */ 
private static String getInt(String num){ 
 //检查格式 
 checkNum(num); 
 
 char[] val = String.valueOf(num).toCharArray(); 
 StringBuffer sb = new StringBuffer(); 
 int t , s = 0; 
 for (int i = 0; i < val.length; i++) { 
 if(val[i]=='.') { 
 break; 
 } 
 t = Integer.parseInt(val[i]+"",16); 
 if(s+t==0){ 
 continue; 
 } 
 sb.append(t); 
 s+=t; 
 } 
 return (sb.length()==0? "0":sb.toString()); 
} 
 
/** 
 * 获取小数部分 
 * 
 * @param num 
 * @return 
 */ 
private static String getFraction(String num){ 
 int i = num.lastIndexOf("."); 
 if(num.indexOf(".") != i){ 
 throw new RuntimeException("数字格式不正确,最多只能有一位小数点!"); 
 } 
 String fraction =""; 
 if(i>=0){ 
 fraction = getInt(new StringBuffer(num).reverse().toString()); 
 if(fraction.equals("0")){ 
 return ""; 
 } 
 } 
 return new StringBuffer(fraction).reverse().toString(); 
} 
 
/** 
 * 检查数字格式 
 * 
 * @param num 
 */ 
private static void checkNum(String num) { 
 if(num.indexOf(".") != num.lastIndexOf(".")){ 
 throw new RuntimeException("数字["+num+"]格式不正确!"); 
 } 
 if(num.indexOf("-") != num.lastIndexOf("-") || num.lastIndexOf("-")>0){ 
 throw new RuntimeException("数字["+num+"]格式不正确!"); 
 } 
 if(num.indexOf("+") != num.lastIndexOf("+")){ 
 throw new RuntimeException("数字["+num+"]格式不正确!"); 
 } 
 if(num.indexOf("+") != num.lastIndexOf("+")){ 
 throw new RuntimeException("数字["+num+"]格式不正确!"); 
 } 
 if(num.replaceAll("[\\d|\\.|\\-|\\+]", "").length()>0){ 
 throw new RuntimeException("数字["+num+"]格式不正确!"); 
 } 
}

通过这种分而治之的思路,处理起来就简单多了。写个main函数调用一下:

public static void main(String[] args) { 
 short s = 10; 
 byte b=10; 
 char c='A'; 
 Object[] nums = {s, b, c, 0, 1001, 100100001L, 21., 205.23F, 205.23D, "01000010", "1000000100105.0123", ".142", "20.00", "1..2", true}; 
 System.out.println("将任意数字转化为汉字(包括整数、小数以及各种类型的数字)"); 
 System.out.println("--------------------------------------------"); 
 for(Object num :nums){ 
 try{ 
 System.out.print("["+num.getClass().getSimpleName()+"]"+num); 
 for(int i=0;i<25-String.valueOf(num+num.getClass().getSimpleName()).length();i+=4){ 
 System.out.print("\t"); 
 } 
 //调用转化为小写和大写 
 System.out.print(" format:"+toChineseLower(num)); 
 System.out.println("【"+toChineseUpper(num)+"】"); 
 }catch(Exception e){ 
 System.out.println(" 错误信息:"+e.getMessage()); 
 } 
 } 
} 

看看结果吧:


从上述代码和运行结果中,我们可以看到该功能支持多种数据类型的转换、支持转化为一般汉字和财务专用大写汉字。还可以智能处理非正常逻辑的数字。比如“20”会转化为“二十”而非“二十零”;“1 0000 0001” 转换成“一亿零一”而非“一亿零万零一”。

这里只分享了一个转换汉字的功能,下篇将分享一下大数相乘、相加、相减的方法。支持小数和负数的运算,敬请期待。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • springboot 整合druid及配置依赖

    springboot 整合druid及配置依赖

    这篇文章主要介绍了springboot 整合druid及jdbc 依赖、数据库依赖(mysql),druid 依赖的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 基于SpringBoot整合oauth2实现token认证

    基于SpringBoot整合oauth2实现token认证

    这篇文章主要介绍了基于SpringBoot整合oauth2实现token 认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Spring中的@CrossOrigin注解的使用详细解读

    Spring中的@CrossOrigin注解的使用详细解读

    这篇文章主要介绍了Spring中的@CrossOrigin注解的使用详细解读,跨源资源共享(CORS),是由大多数浏览器实现的W3C规范,允许对跨域请求进行灵活授权,用来代替IFRAME或JSONP等非正规实现方式,需要的朋友可以参考下
    2023-11-11
  • Spring通过c3p0配置bean连接数据库

    Spring通过c3p0配置bean连接数据库

    这篇文章主要为大家详细介绍了Spring通过c3p0配置bean连接数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 详解Java方法method的定义与调用及重载

    详解Java方法method的定义与调用及重载

    方法,也称函数,如果想要重复一段或者多段代码块的使用,可以将这些代码封装成一个方法,方法具体表现为某种行为,使用方法可以提高代码的复用性
    2022-04-04
  • Java日期时间使用方法汇总

    Java日期时间使用方法汇总

    这篇文章主要针对Java日期时间使用方法进行汇总,感兴趣的朋友可以参考一下
    2016-03-03
  • Java中的定时器Timer详解

    Java中的定时器Timer详解

    这篇文章主要为大家详细介绍了Java定时器Timer的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • IDEA 2020.1 搜索不到Chinese ​(Simplified)​ Language Pack EAP,无法安装的问题

    IDEA 2020.1 搜索不到Chinese ​(Simplified)​ Language

    小编在安装中文插件时遇到IDEA 2020.1 搜索不到Chinese &#8203;(Simplified)&#8203; Language Pack EAP,无法安装的问题,本文给大家分享我的解决方法,感兴趣的朋友一起看看吧
    2020-04-04
  • java学习之猜数字小游戏

    java学习之猜数字小游戏

    这篇文章主要为大家详细介绍了java学习之猜数字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Java配置HTTP/Socks代理的简单快速上手方法

    Java配置HTTP/Socks代理的简单快速上手方法

    这篇文章主要为大家介绍了Java配置HTTP/Socks代理的简单快速上手方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论