需求如下:用json讀取后台工時信息,比如23.5小時,需要通過編碼將其轉換為貳拾叄點伍
比如23.23之前有對Stringl類型強轉為Double在轉為整型,發生了精度丟失,后來想想對小數點進行分割是個辦法
編碼實現如下:
package day1; import java.util.ArrayList; import java.util.Collections; import java.util.regex.Pattern; public class test_5 { /** * 單位進位,中文默認為4位即(萬、億) */ public static int UNIT_STEP = 4; /** * 單位 */ public static String[] CN_UNITS = new String[] { "個", "十", "百", "千", "萬", "十", "百", "千", "億", "十", "百", "千", "萬" }; /** * 漢字 */ public static String[] CN_CHARS = new String[] { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; /** * 將阿拉伯數字轉換為中文數字123=》一二三 * * @param srcNum * @return */ public static String getCNNum(int srcNum) { String desCNNum = ""; if (srcNum <= 0) desCNNum = "零"; else { int singleDigit; while (srcNum > 0) { singleDigit = srcNum % 10; desCNNum = String.valueOf(CN_CHARS[singleDigit]) + desCNNum; srcNum /= 10; } } return desCNNum; } /** * 數值轉換為中文字符串 如2轉化為貳 */ public String cvt(long num) { return this.cvt(num, false); } /** * 數值轉換為中文字符串(口語化) * * @param num * 需要轉換的數值 * @param isColloquial * 是否口語化。例如12轉換為'十二'而不是'一十二'。 * @return */ public String cvt(String num, boolean isColloquial) { int integer, decimal; StringBuffer strs = new StringBuffer(32); String[] splitNum = num.split("\\."); integer = Integer.parseInt(splitNum[0]); //整數部分 decimal = Integer.parseInt(splitNum[1]); //小數部分 String[] result_1 =convert(integer, isColloquial); for (String str1 : result_1) strs.append(str1); if(decimal==0){//小數部分為0時 return strs.toString(); }else{ String result_2 =getCNNum(decimal); //例如5.32,小數部分展示三二,而不是三十二 strs.append("點"); strs.append(result_2); return strs.toString(); } } /* * 對於int,long類型的數據處理 */ public String cvt(long num, boolean isColloquial) { String[] result = this.convert(num, isColloquial); StringBuffer strs = new StringBuffer(32); for (String str : result) { strs.append(str); } return strs.toString(); } /** * 將數值轉換為中文 * * @param num * 需要轉換的數值 * @param isColloquial * 是否口語化。例如12轉換為'十二'而不是'一十二'。 * @return */ public String[] convert(long num, boolean isColloquial) { if (num < 10) {// 10以下直接返回對應漢字 return new String[] { CN_CHARS[(int) num] };// ASCII2int } char[] chars = String.valueOf(num).toCharArray(); if (chars.length > CN_UNITS.length) {// 超過單位表示范圍的返回空 return new String[] {}; } boolean isLastUnitStep = false;// 記錄上次單位進位 ArrayList<String> cnchars = new ArrayList<String>(chars.length * 2);// 創建數組,將數字填入單位對應的位置 for (int pos = chars.length - 1; pos >= 0; pos--) {// 從低位向高位循環 char ch = chars[pos]; String cnChar = CN_CHARS[ch - '0'];// ascii2int 漢字 int unitPos = chars.length - pos - 1;// 對應的單位坐標 String cnUnit = CN_UNITS[unitPos];// 單位 boolean isZero = (ch == '0');// 是否為0 boolean isZeroLow = (pos + 1 < chars.length && chars[pos + 1] == '0');// 是否低位為0 boolean isUnitStep = (unitPos >= UNIT_STEP && (unitPos % UNIT_STEP == 0));// 當前位是否需要單位進位 if (isUnitStep && isLastUnitStep) {// 去除相鄰的上一個單位進位 int size = cnchars.size(); cnchars.remove(size - 1); if (!CN_CHARS[0].equals(cnchars.get(size - 2))) {// 補0 cnchars.add(CN_CHARS[0]); } } if (isUnitStep || !isZero) {// 單位進位(萬、億),或者非0時加上單位 cnchars.add(cnUnit); isLastUnitStep = isUnitStep; } if (isZero && (isZeroLow || isUnitStep)) {// 當前位為0低位為0,或者當前位為0並且為單位進位時進行省略 continue; } cnchars.add(cnChar); isLastUnitStep = false; } Collections.reverse(cnchars); // 清除最后一位的0 int chSize = cnchars.size(); String chEnd = cnchars.get(chSize - 1); if (CN_CHARS[0].equals(chEnd) || CN_UNITS[0].equals(chEnd)) { cnchars.remove(chSize - 1); } // 口語化處理 if (isColloquial) { String chFirst = cnchars.get(0); String chSecond = cnchars.get(1); if (chFirst.equals(CN_CHARS[1]) && chSecond.startsWith(CN_UNITS[1])) {// 是否以'一'開頭,緊跟'十' cnchars.remove(0); } } return cnchars.toArray(new String[] {}); } public static void main(String[] args) { test_5 temp = new test_5(); String i ="40.3"; int t = 2234; double j = 221.23; System.out.println(temp.cvt(i,true));//四十點三 System.out.println(temp.cvt(t,true));//二千二百三十四 System.out.println(temp.cvt(""+j,true));//二百二十一點二三 } }