iT邦幫忙

0

應用系統建置前準備工具 - TypeConvert 各類型別轉換工具

  • 分享至 

  • xImage
  •  

TypeConvert 型別轉換工具類別

概述

TypeConvert 是一個全方位的型別轉換工具類別,提供各種 Java 資料型別之間的轉換功能,包含基本型別、數字型別、字串、陣列、編碼轉換、半形/全形字轉換,以及數字金額的中文大寫轉換等。此類別設計為靜態工具類別,不允許建立實例。

專案相關程式

第三方元件(Dependency)

  • org.apache.commons.lang3;

主要功能

1. 基本型別轉換

字串轉換

// 物件轉字串
String str = TypeConvert.toString(object);
String strWithDefault = TypeConvert.toString(object, "預設值");

// 字元轉換
Character ch = TypeConvert.toChar("ABC");  // 返回 'A'
Character chWithDefault = TypeConvert.toChar(null, 'x');

數值型別轉換

// 數字型別轉換
Byte b = TypeConvert.toByte("123");
Short s = TypeConvert.toShort("456");
Integer i = TypeConvert.toInteger("789");
Long l = TypeConvert.toLong("1000");
Float f = TypeConvert.toFloat("12.34");
Double d = TypeConvert.toDouble("56.78");

// 大數字型別
BigInteger bi = TypeConvert.toBigInteger("123456789");
BigDecimal bd = TypeConvert.toBigDecimal("123.456");

// 通用數字轉換
Number n = TypeConvert.toNumber("123.45");

布林值轉換

// 支援多種布林值表示
Boolean b1 = TypeConvert.toBoolean("true");   // true
Boolean b2 = TypeConvert.toBoolean("yes");    // true
Boolean b3 = TypeConvert.toBoolean("1");      // true
Boolean b4 = TypeConvert.toBoolean("false");  // false
Boolean b5 = TypeConvert.toBoolean("no");     // false
Boolean b6 = TypeConvert.toBoolean("0");      // false

2. 陣列與集合轉換

字串分割轉陣列

// 預設使用逗號分隔
Integer[] intArr = TypeConvert.toIntArray("1,2,3");
Long[] longArr = TypeConvert.toLongArray("100,200,300");
String[] strArr = TypeConvert.toStrArray("a,b,c");

// 自訂分隔符
Integer[] customArr = TypeConvert.toIntArray(";", "1;2;3");

串列操作

// 串列轉字串
String result = TypeConvert.arrayListToString(list);
String resultWithDelimiter = TypeConvert.mergeListStringToString(list, ",");

// 串列與位元組轉換
byte[] bytes = TypeConvert.stringArrayListToByte(stringList);
List<String> list = TypeConvert.byteToStringArrayList(bytes);

3. 編碼轉換

字元集轉換

// UTF-8 轉換
String utf8Str = TypeConvert.toUtf8String(object);

// 自訂字元集
String result = TypeConvert.convertCharset(object, "UTF-8");
String result2 = TypeConvert.convertCharset(bytes, Charset.forName("UTF-8"));

十六進位轉換

// 位元組陣列與十六進位互轉
String hex = TypeConvert.bytesToHexString(bytes);
byte[] bytes = TypeConvert.hexStringToBytes(hexString);

// 字串轉十六進位
String hex = TypeConvert.stringToHexString("測試文字");

4. 序列化與反序列化

Base64 轉換

// 物件序列化為 Base64
String base64 = TypeConvert.objectToBase64String(object);
Object obj = TypeConvert.base64StringToObject(base64String);

Blob 轉換

// 物件與 Blob 互轉
Blob blob = TypeConvert.objectToBlob(object);
Object obj = TypeConvert.blobToObject(blob);

5. 特殊轉換功能

全形半形轉換

// 半形轉全形
String full = TypeConvert.toFullChar("ABC123");  // 轉為全形
String half = TypeConvert.toHalfChar("ABC123");  // 轉為半形

// 可指定不轉換的字元
Set<Character> notConvert = new HashSet<>();
notConvert.add('A');
String result = TypeConvert.toFullChar("ABC", notConvert);

數字金額大寫

// 數字轉中文大寫金額
String amount = TypeConvert.digitUppercase(10250.75); 
// 輸出:壹萬零貳佰伍拾元柒角伍分

重要注意事項

  1. 異常處理

    • 大多數方法在轉換失敗時返回 null 或預設值
    • 序列化相關方法可能拋出 IOException
    • Blob 操作可能拋出 SQLException
  2. 數值轉換

    • 支援科學記數法(如 "1e10")
    • 使用 BigDecimal 處理大數值,避免精度問題
    • 數字格式錯誤時返回預設值
  3. 字元集轉換

    • 預設使用系統字元集
    • 支援 byte[]、ByteBuffer 等多種輸入格式
    • 建議明確指定字元集避免編碼問題
  4. 記憶體考量

    • 大量資料轉換時注意記憶體使用
    • 序列化大物件時可能需要較多記憶體

單元測試範例

以下測試範例示範 TypeConvert 常見轉換函式驗證:

1. 基本型別轉換

@Test
void testPrimitiveConversions() {
   assertEquals("123", TypeConvert.toString(123));
   assertEquals(Integer.valueOf(123), TypeConvert.toInteger("123"));
   assertTrue(TypeConvert.toBoolean("yes"));
   assertFalse(TypeConvert.toBoolean("no"));
}

2. 陣列與集合轉換

@Test
void testArrayAndListConversions() {
   Integer[] arr = TypeConvert.toIntArray("1,2,3");
   assertArrayEquals(new Integer[]{1,2,3}, arr);

   List<String> list = Arrays.asList("a","b");
   byte[] bytes = TypeConvert.stringArrayListToByte(new ArrayList<>(list));
   List<String> back = TypeConvert.byteToStringArrayList(bytes);
   assertEquals(list, back);
}

3. 十六進位/Bytes 轉換

@Test
void testHexConversion() {
   byte[] bytes = "abc".getBytes(StandardCharsets.UTF_8);
   String hex = TypeConvert.bytesToHexString(bytes);
   assertNotNull(hex);
   assertArrayEquals(bytes, TypeConvert.hexStringToBytes(hex));
}

4. 特殊轉換

@Test
void testDigitUppercase() {
   String s = TypeConvert.digitUppercase(10250.75);
   assertNotNull(s);
   assertTrue(s.contains("元"));
}

測試說明

  • 驗證基本型別與集合之間的互轉
  • 驗證 bytes/hex 與數字大寫轉換

程式碼 TypeConvert.java

package tw.lewishome.webapp.base.utility.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.sql.Blob;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Set;

import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialException;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;


/**
 * 各類物件型別轉換工具類
 *
 * 提供各種物件型別之間的轉換方法,包括基本型別、數字型別、字串、陣列、編碼轉換、半形全形字轉換及數字大寫中文轉換等。
 * 所有方法皆支援轉換失敗時回傳預設值或 null。
 *
 *
 * <ul>
 * <li>toString:物件轉字串,支援預設值。</li>
 * <li>toChar:物件轉字元,支援預設值。</li>
 * <li>toByte/toShort/toInteger/toLong/toDouble/toFloat/toNumber:物件轉各種數字型別,支援預設值。</li>
 * <li>toBoolean:物件轉布林值,支援常見字串(true/false/yes/no/ok/1/0)。</li>
 * <li>toBigInteger/toBigDecimal:物件轉大數型別,支援預設值。</li>
 * <li>toIntArray/toLongArray/toStrArray:字串分隔轉陣列。</li>
 * <li>convertCharset/toUtf8String:物件編碼轉字串,支援 byte[]、Byte[]、ByteBuffer。</li>
 * <li>toFullChar/toHalfChar:半形字與全形字互轉,支援排除不轉換字元。</li>
 * <li>digitUppercase:數字金額轉大寫中文數字。</li>
 * </ul>
 *
 *
 * 所有方法皆為 static,無須實例化即可使用。
 * 
 *
 * @author Lewis
 */
public class TypeConvert {

    // Private constructor to prevent instantiation
    private TypeConvert() {
        throw new IllegalStateException("This is a utility class and cannot be instantiated");
    }

    /**
     * 物件轉換字串(String)<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return String 轉換結果
     */
    public static String toString(Object value, String defaultValue) {
        if (null == value) {
            return defaultValue;
        }
        if (value instanceof String stringValue) {
            return stringValue;
        }
        return value.toString();
    }

    /**
     * 物件轉換字串(String)<br>
     * 如果轉換失敗,回傳的null<br>
     *
     * @param value 被轉換物件
     * @return String 轉換結果
     */
    public static String toString(Object value) {
        return toString(value, null);
    }

    /**
     * 物件轉換字元 (char)<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Character 轉換結果
     */
    public static Character toChar(Object value, Character defaultValue) {
        if (null == value) {
            return defaultValue;
        }
        if (value instanceof Character characterValue) {
            return characterValue;
        }

        String stringValue = toString(value, null);
        if (StringUtils.isBlank(stringValue)) {
            return defaultValue;
        } else {
            return stringValue.charAt(0);
        }
    }

    /**
     * 物件轉換字元 (char)<br>
     * 如果轉換失敗,回傳 Null<br>
     *
     * @param value 被轉換物件
     * @return Character 轉換結果
     */
    public static Character toChar(Object value) {
        return toChar(value, null);
    }

    /**
     * 物件轉換位元組 (byte)<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Byte 轉換結果
     */
    public static Byte toByte(Object value, Byte defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Byte byteValue) {
            return byteValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.byteValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return Byte.parseByte(stringValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換位元組 (byte)<br>
     * 如果轉換失敗,回傳 Null<br>
     *
     * @param value 被轉換物件
     * @return Byte 轉換結果
     */
    public static Byte toByte(Object value) {
        return toByte(value, null);
    }

    /**
     * 物件轉換Short數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Short 轉換結果
     */
    public static Short toShort(Object value, Short defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Short shortValue) {
            return shortValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.shortValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return Short.parseShort(stringValue.trim());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換Short數字<br>
     * 如果轉換失敗,回傳 Null<br>
     *
     * @param value 被轉換物件
     * @return Short 轉換結果
     */
    public static Short toShort(Object value) {
        return toShort(value, null);
    }

    /**
     * 物件轉換Number數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Number 轉換結果
     */
    public static Number toNumber(Object value, Number defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue;
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return NumberFormat.getInstance().parse(stringValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換Number數字<br>
     * 如果轉換失敗,回傳 Null<br>
     *
     * @param value 被轉換物件
     * @return Number 轉換結果
     */
    public static Number toNumber(Object value) {
        return toNumber(value, null);
    }

    /**
     * 物件轉換 Integer 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Integer 轉換結果
     */
    public static Integer toInteger(Object value, Integer defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Integer integerValue) {
            return integerValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.intValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(stringValue.trim());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 Integer 數字<br>
     * 如果轉換失敗,回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Integer 轉換結果
     */
    public static Integer toInteger(Object value) {
        return toInteger(value, null);
    }

    /**
     * String 分隔 Integer Array<br>
     *
     * @return Integer Array 轉換結果
     * @param value a String object
     */
    public static Integer[] toIntArray(String value) {
        return toIntArray(",", value);
    }

    /**
     * String 分隔 Long Array<br>
     *
     * @return Long Array 轉換結果
     * @param value a String object
     */
    public static Long[] toLongArray(String value) {
        return toLongArray(",", value);
    }

    /**
     * String 分隔 Integer Array<br>
     *
     * @param split 分隔符號
     * @param value 被轉換的String
     * @return 結果
     */
    public static Integer[] toIntArray(String split, String value) {
        if (StringUtils.isEmpty(value)) {
            return new Integer[] {};
        }
        String[] stringArray = value.split(split);
        Integer[] intArray = new Integer[stringArray.length];
        for (int i = 0; i < stringArray.length; i++) {
            Integer v = toInteger(stringArray[i], 0);
            intArray[i] = v;
        }
        return intArray;
    }

    /**
     * String 分隔 Long Array<br>
     *
     * @param split 分隔符號
     * @param value 被轉換的String
     * @return 結果
     */
    public static Long[] toLongArray(String split, String value) {
        if (StringUtils.isEmpty(value)) {
            return new Long[] {};
        }
        String[] stringArray = value.split(split);
        Long[] longs = new Long[stringArray.length];
        for (int i = 0; i < stringArray.length; i++) {
            Long v = toLong(stringArray[i], null);
            longs[i] = v;
        }
        return longs;
    }

    /**
     * String 分隔 Long Array<br>
     *
     * @param value 被轉換的String
     * @return 結果
     */
    public static String[] toStrArray(String value) {
        if (StringUtils.isEmpty(value)) {
            return new String[] {};
        }
        return toStrArray(",", value);
    }

    /**
     * String 分隔 String Array <br>
     *
     * @param split 分隔符號
     * @param value 被轉換的String
     * @return 結果
     */
    public static String[] toStrArray(String split, String value) {
        return value.split(split);
    }

    /**
     * 物件Object轉換Blob格式
     *
     * @param inObject 物件
     * @return Blob Blob格式
     * @throws IOException IOException
     * @throws SerialException SerialException
     * @throws SQLException SQLException
     */
    public static Blob objectToBlob(Object inObject) throws IOException, SerialException, SQLException {
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            ObjectOutputStream objectOutputStream = null;

            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);

            objectOutputStream.writeObject(inObject);
            objectOutputStream.flush();
            return new SerialBlob(byteArrayOutputStream.toByteArray());
        }
    }

    /**
     * 物件Blob轉換Object格式
     *
     * @param inBlob Blob格式
     * @return Object 物件
     */
    public static Object blobToObject(Blob inBlob) {
        try {
            int buteLength = (int) inBlob.length();
            byte[] data = inBlob.getBytes(1, buteLength);
            ByteArrayInputStream in = new ByteArrayInputStream(data);
            ObjectInputStream objectInputStream = new ObjectInputStream(in);
            return objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * String Array List 轉換為 byte[] (文字檔適用)
     *
     * @return ByteArray byte array
     * @param stringArrayList a {@link java.util.ArrayList} object
     */
    public static byte[] stringArrayListToByte(List<String> stringArrayList) {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
        try {
            for (String element : stringArrayList) {
                dataOutputStream.writeUTF(element);
            }
            dataOutputStream.close();

            byteArrayOutputStream.close();
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
        return byteArrayOutputStream.toByteArray();

    }

    /**
     * List String合併成長字串
     *
     * @param inArrayList ArrayList 字串 (加入 分隔字串)
     * @param delimiter   字串分隔符號
     * @return String 合併後的長字串
     */
    public static String arrayListToString(List<String> inArrayList, String delimiter) {

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < inArrayList.size(); i++) {
            String oneArrayList = inArrayList.get(i).trim();
            stringBuilder.append(oneArrayList);
        }
        return stringBuilder.toString();
    }

    /**
     * List String合併成長字串
     *
     * @param inArrayList ArrayList 字串
     * @return String 合併後的長字串
     */
    public static String arrayListToString(List<String> inArrayList) {
        return arrayListToString(inArrayList, "");
    }

     /**
     * List String 合併成長字串
     *
     * @param inArrayList ArrayList 字串
     * @return String 合併後的長字串
     */
    public static String mergeListStringToString(List<String> inArrayList) {
        return mergeListStringToString(inArrayList, "");
    }

    /**
     * List String 合併成長字串 (加入 分隔字串)
     *
     * @param inArrayList ArrayList 字串
     * @param delimiter   字串分隔符號
     * @return String 合併後的長字串
     */
    public static String mergeListStringToString(List<String> inArrayList, String delimiter) {

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < inArrayList.size(); i++) {
            String oneArrayList = inArrayList.get(i).trim();
            stringBuilder.append(oneArrayList).append(delimiter);
        }
        return stringBuilder.toString();
    }

    /**
     * byte[] 轉換為 String Array List (文字檔適用)
     * 
     * @param bytes an array of {@link byte} objects
     * @return List String 字串ArrayList
     */
    public static List<String> byteToStringArrayList(byte[] bytes) {
        List<String> rtnArraylist = new ArrayList<>();
        // write to byte array
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);
        try {
            while (dataInputStream.available() > 0) {
                String element = dataInputStream.readUTF();
                rtnArraylist.add(element);
            }
            dataInputStream.close();
            byteArrayInputStream.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return rtnArraylist;
    }

    /**
     * Object to Base64String
     *
     * @return String base64String
     * @param serializableObject a {@link java.io.Serializable} object
     * @throws IOException IOException
     */
    public static String objectToBase64String(Serializable serializableObject) throws IOException {

        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(serializableObject);
            return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
        }
    }

    /**
     * Base64String to Object
     *
     * @return Object serializableObj
     * @param base64String a String object
     * @throws IOException            IOException
     * @throws ClassNotFoundException ClassNotFoundException
     */
    public static Object base64StringToObject(String base64String) throws ClassNotFoundException, IOException {

        byte[] byteArray = Base64.getDecoder().decode(base64String);
        try (ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(byteArray))) {
            return objectInputStream.readObject();
        }
    }

    /**
     * byte[] 轉換為 HexString
     *
     * @return String HexString
     * @param bytes an array of {@link byte} objects
     */

    public static String bytesToHexString(byte[] bytes) {
        StringBuilder stringBuilder = new StringBuilder();
        for (byte byteValue : bytes) {
            String hex = Integer.toHexString(byteValue & 0xFF);
            if (hex.length() == 1) {
                stringBuilder.append('0');
            }
            stringBuilder.append(hex);
        }
        return stringBuilder.toString();
    }

    /**
     * String 轉換為 HexString
     *
     * @return String HexString
     * @param value a String object
     */

    public static String stringToHexString(String value) {
        byte[] bytesValue = value.getBytes();
        return bytesToHexString(bytesValue);
    }

    /**
     * HexString 轉換為 byte[]
     *
     * @return byte[] byte array
     * @param value a String object
     */

    public static byte[] hexStringToBytes(String value) {
        int len = value.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(value.charAt(i), 16) << 4)
                    + Character.digit(value.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * 物件轉換 Long 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static Long toLong(Object value, Long defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Long longValue) {
            return longValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.longValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            // BigDecimal 用來處理過大的數字
            return new BigDecimal(stringValue.trim()).longValue();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 Long 數字<br>
     * 如果轉換失敗,回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static Long toLong(Object value) {
        return toLong(value, null);
    }

    /**
     * 物件轉換 Double 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static Double toDouble(Object value, Double defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Double doubleValue) {
            return doubleValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.doubleValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            // BigDecimal 用來處理過大的數字
            return new BigDecimal(stringValue.trim()).doubleValue();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 Double 數字<br>
     * 如果轉換失敗,回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static Double toDouble(Object value) {
        return toDouble(value, null);
    }

    /**
     * 物件轉換 Float 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static Float toFloat(Object value, Float defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Float floatValue) {
            return floatValue;
        }
        if (value instanceof Number numberValue) {
            return numberValue.floatValue();
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try { // Float 解析
            return Float.parseFloat(stringValue.trim());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 Float 數字<br>
     * 如果轉換失敗,回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static Float toFloat(Object value) {
        return toFloat(value, null);
    }

    /**
     * 物件轉換 Boolean 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static Boolean toBoolean(Object value, Boolean defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof Boolean booleanValue) {
            return booleanValue;
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        stringValue = stringValue.trim().toLowerCase();
        switch (stringValue) {
            case "true", "yes", "ok", "1":
                return true;
            case "false", "no", "0":
                return false;
            default:
                return defaultValue;
        }
    }

    /**
     * 物件轉換 Boolean 數字 <br>
     * 如果轉換失敗,回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static Boolean toBoolean(Object value) {
        return toBoolean(value, null);
    }

    /**
     * 物件轉換 BigInteger 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof BigInteger bigIntegerValue) {
            return bigIntegerValue;
        }
        if (value instanceof Long longValue) {
            return BigInteger.valueOf(longValue);
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return new BigInteger(stringValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 BigInteger 數字<br>
     * 如果轉換失敗回傳 Null <br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static BigInteger toBigInteger(Object value) {
        return toBigInteger(value, null);
    }

    /**
     * 物件轉換 BigDecimal 數字<br>
     * 如果轉換失敗,回傳的DefaultValue<br>
     *
     * @param value        被轉換物件
     * @param defaultValue DefaultValue
     * @return Long 轉換結果
     */
    public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        if (value instanceof BigDecimal bigDecimalValue) {
            return bigDecimalValue;
        }
        if (value instanceof Long longValue) {
            return new BigDecimal(longValue);
        }
        if (value instanceof Double doubleValue) {
            return BigDecimal.valueOf(doubleValue);
        }
        if (value instanceof Integer integerValue) {
            return new BigDecimal(integerValue);
        }
        String stringValue = toString(value, null);
        if (StringUtils.isEmpty(stringValue)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(stringValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 物件轉換 BigDecimal 數字<br>
     * 如果轉換失敗回傳 Null<br>
     *
     * @param value 被轉換物件
     * @return Long 轉換結果
     */
    public static BigDecimal toBigDecimal(Object value) {
        return toBigDecimal(value, null);
    }

    /**
     * 將物件轉為UTF-8字串
     *
     * @param object 物件
     * @return String 字串
     */
    public static String toUtf8String(Object object) {
        return convertCharset(object, "UTF-8");
    }

    /**
     * 將物件轉為指定字元集的字串
     *
     * @param object      物件
     * @param charsetName 字元集名稱
     * @return String 字串
     */
    public static String convertCharset(Object object, String charsetName) {
        return convertCharset(object, Charset.forName(charsetName));
    }

    /**
     * 將物件轉為指定字元集的字串
     *
     * @param object  物件
     * @param charset 字元集
     * @return String 字串
     */
    public static String convertCharset(Object object, Charset charset) {
        if (null == object) {
            return null;
        }

        if (object instanceof String stringValue) {
            return stringValue;
        } else if (object instanceof byte[] byteArrayValue) {
            return convertCharset(byteArrayValue, charset);
        } else if (object instanceof Byte[] byteArrayValue) {
            byte[] bytes = ArrayUtils.toPrimitive(byteArrayValue);
            return convertCharset(bytes, charset);
        } else if (object instanceof ByteBuffer byteBufferValue) {
            return convertCharset(byteBufferValue, charset);
        }
        return object.toString();
    }

    /**
     * 將 Byte Array 轉為指定字元集的字串
     *
     * @param bytes   Byte Array
     * @param charset 字元集字串,使用系統 Default 字碼
     * @return String 字串
     */

    public static String convertCharset(byte[] bytes, String charset) {
        return convertCharset(bytes,
                StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
    }

    /**
     * 將 Byte Array 轉為指定字元集 *
     * 
     * @param data    Byte Array
     * @param charset 字元集,如果空值,則使用作業系統預設字元集
     * @return String 字串
     */
    public static String convertCharset(byte[] data, Charset charset) {
        if (data == null) {
            return null;
        }

        if (null == charset) {
            return new String(data);
        }
        return new String(data, charset);
    }

    /**
     * 將編碼的byteBuffer資料轉為字串
     *
     * @param data    資料
     * @param charset 字碼名稱,使用系統 Default 字碼
     * @return String 字串
     */
    public static String convertCharset(ByteBuffer data, String charset) {
        if (data == null) {
            return null;
        }

        return convertCharset(data, Charset.forName(charset));
    }

    /**
     * 將編碼的byteBuffer資料轉為字串
     *
     * @param data    資料
     * @param charset 字碼,使用系統 Default 字碼
     * @return String 字串
     */
    public static String convertCharset(ByteBuffer data, Charset charset) {

        if (null == charset) {
            charset = Charset.defaultCharset();
        }
        System.out.println(charset.displayName());
        // System.out.println(charset.decode(data).toString());
        return charset.decode(data).toString();
    }

    // ==== 半形字全形字轉換換
    /**
     * 半形字轉全形字
     *
     * @param input String.
     * @return 全形字串.
     */
    public static String toFullChar(String input) {
        return toFullChar(input, null);
    }

    /**
     * 半形字轉全形字
     *
     * @param input         String
     * @param notConvertSet 不替換的字碼
     * @return 全形字串.
     */
    public static String toFullChar(String input, Set<Character> notConvertSet) {
        char[] arrayChar = input.toCharArray();
        for (int i = 0; i < arrayChar.length; i++) {
            if (null != notConvertSet && notConvertSet.contains(arrayChar[i])) {
                // 跳過不替換的字符
                continue;
            }

            if (arrayChar[i] == ' ') {
                arrayChar[i] = '\u3000';
            } else if (arrayChar[i] < '\177') {
                arrayChar[i] = (char) (arrayChar[i] + 65248);

            }
        }
        return new String(arrayChar);
    }

    /**
     * 全形字轉半形字
     *
     * @param input String.
     * @return 半角字符串
     */
    public static String toHalfChar(String input) {
        return toHalfChar(input, null);
    }

    /**
     * 全形空白字轉半形字 (全形空白、數字、英文字)
     *
     * @param text          文本
     * @param notConvertSet 不轉換的字碼
     * @return 轉換半形空白
     */
    public static String toHalfChar(String text, Set<Character> notConvertSet) {
        char[] arrayChar = text.toCharArray();
        for (int i = 0; i < arrayChar.length; i++) {
            if (null != notConvertSet && notConvertSet.contains(arrayChar[i])) {
                // 跳過不替換的字符
                continue;
            }

            if (arrayChar[i] == '\u3000') // 全形空白字元碼 U+3000
            {
                arrayChar[i] = ' ';
            } else if (arrayChar[i] > '\uFF00' && arrayChar[i] < '\uFF5F') {
                arrayChar[i] = (char) (arrayChar[i] - 65248); // 全形數字、英文字元碼 (char -)
            }
        }
        String returnString = new String(arrayChar);

        return returnString;
    }

    /**
     * 數字金額轉大寫數中文字
     *
     * @param doubleNumber 數字
     * @return 大寫中文數字
     */
    public static String digitUppercase(double doubleNumber) {
        String[] fraction = { "角", "分" };
        String[] digit = { "零", "壹", "貳", "叄", "肆", "伍", "陸", "柒", "捌", "玖" };
        String[][] unit = { { "元", "萬", "億" }, { "", "拾", "佰", "仟" } };

        String head = doubleNumber < 0 ? "負" : "";
        doubleNumber = Math.abs(doubleNumber);

        String stringResult = "";
        StringBuilder resultStringBuilder = new StringBuilder();
        for (int i = 0; i < fraction.length; i++) {
            // double計算會又誤差問題
            BigDecimal nNum = BigDecimal.valueOf(doubleNumber);
            BigDecimal decimal = BigDecimal.valueOf(10);
            BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
            double d = scale.doubleValue();
            resultStringBuilder.append(
                    (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""));
        }
        if (StringUtils.isBlank(stringResult)) {
            resultStringBuilder.append("整");
        }
        int integerPart = (int) Math.floor(doubleNumber);

        for (int i = 0; i < unit[0].length && integerPart > 0; i++) {
            StringBuilder partialStringBuilder = new StringBuilder();
            for (int j = 0; j < unit[1].length && doubleNumber > 0; j++) {
                partialStringBuilder.insert(0, digit[integerPart % 10] + unit[1][j]);
                integerPart = integerPart / 10;
            }
            resultStringBuilder.insert(0, partialStringBuilder.toString().replaceAll("^$", "零") + unit[0][i]);
        }

        return head + resultStringBuilder.toString().replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "")
                .replaceAll("(零.)+", "零").replaceAll("^整$",
                        "零元整");
    }
}

單元測試程式碼 TypeConvertTest.java

package tw.lewishome.webapp.base.utility.common;

import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;


import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.sql.rowset.serial.SerialException;

class TypeConvertTest {

    @Test
    void testToString() {
        assertEquals("abc", TypeConvert.toString("abc"));
        assertEquals("123", TypeConvert.toString(123));
        assertNull(TypeConvert.toString(null));
        assertEquals("default", TypeConvert.toString(null, "default"));
    }

    @Test
    void testToChar() {
        assertEquals(Character.valueOf('a'), TypeConvert.toChar('a'));
        assertEquals(Character.valueOf('1'), TypeConvert.toChar("123"));
        assertNull(TypeConvert.toChar(""));
        assertEquals(Character.valueOf('x'), TypeConvert.toChar(null, 'x'));
    }

    @Test
    void testToByte() {
        assertEquals(Byte.valueOf((byte) 5), TypeConvert.toByte(5));
        assertEquals(Byte.valueOf((byte) 7), TypeConvert.toByte("7"));
        assertNull(TypeConvert.toByte("abc"));
        assertEquals(Byte.valueOf((byte) 9), TypeConvert.toByte(null, (byte) 9));
    }

    @Test
    void testToShort() {
        assertEquals(Short.valueOf((short) 10), TypeConvert.toShort(10));
        assertEquals(Short.valueOf((short) 20), TypeConvert.toShort("20"));
        assertNull(TypeConvert.toShort("abc"));
        assertEquals(Short.valueOf((short) 30), TypeConvert.toShort(null, (short) 30));
    }

    @Test
    void testToNumber() {
        assertEquals(123, TypeConvert.toNumber("123").intValue());
        assertEquals(123.45, TypeConvert.toNumber("123.45").doubleValue());
        assertNull(TypeConvert.toNumber("abc"));
        assertEquals(99, TypeConvert.toNumber(null, 99).intValue());
    }

    @Test
    void testToInteger() {
        assertEquals(Integer.valueOf(42), TypeConvert.toInteger(42));
        assertEquals(Integer.valueOf(55), TypeConvert.toInteger("55"));
        assertNull(TypeConvert.toInteger("abc"));
        assertEquals(Integer.valueOf(77), TypeConvert.toInteger(null, 77));
    }

    @Test
    void testToIntArray() {
        assertArrayEquals(new Integer[] { 1, 2, 3 }, TypeConvert.toIntArray("1,2,3"));
        assertArrayEquals(new Integer[] {}, TypeConvert.toIntArray(""));
        assertArrayEquals(new Integer[] { 4, 5 }, TypeConvert.toIntArray(";", "4;5"));
    }

    @Test
    void testToLongArray() {
        assertArrayEquals(new Long[] { 1L, 2L, 3L }, TypeConvert.toLongArray("1,2,3"));
        assertArrayEquals(new Long[] {}, TypeConvert.toLongArray(""));
        assertArrayEquals(new Long[] { 4L, 5L }, TypeConvert.toLongArray(";", "4;5"));
    }

    @Test
    void testToStrArray() {
        assertArrayEquals(new String[] { "a", "b", "c" }, TypeConvert.toStrArray("a,b,c"));
        assertArrayEquals(new String[] {}, TypeConvert.toStrArray(""));
        assertArrayEquals(new String[] { "x", "y" }, TypeConvert.toStrArray(";", "x;y"));
    }

    @Test
    void testToLong() {
        assertEquals(Long.valueOf(123L), TypeConvert.toLong(123L));
        assertEquals(Long.valueOf(456L), TypeConvert.toLong("456"));
        assertNull(TypeConvert.toLong("abc"));
        assertEquals(Long.valueOf(789L), TypeConvert.toLong(null, 789L));
        assertEquals(Long.valueOf(10000000000L), TypeConvert.toLong("1e10"));
    }

    @Test
    void testToDouble() {
        assertEquals(Double.valueOf(1.23), TypeConvert.toDouble(1.23));
        assertEquals(Double.valueOf(4.56), TypeConvert.toDouble("4.56"));
        assertNull(TypeConvert.toDouble("abc"));
        assertEquals(Double.valueOf(7.89), TypeConvert.toDouble(null, 7.89));
        assertEquals(Double.valueOf(1e5), TypeConvert.toDouble("1e5"));
    }

    @Test
    void testToFloat() {
        assertEquals(Float.valueOf(1.23f), TypeConvert.toFloat(1.23f));
        assertEquals(Float.valueOf(4.56f), TypeConvert.toFloat("4.56"));
        assertNull(TypeConvert.toFloat("abc"));
        assertEquals(Float.valueOf(7.89f), TypeConvert.toFloat(null, 7.89f));
    }

    @Test
    void testToBoolean() {
        assertTrue(TypeConvert.toBoolean("true"));
        assertTrue(TypeConvert.toBoolean("yes"));
        assertTrue(TypeConvert.toBoolean("ok"));
        assertTrue(TypeConvert.toBoolean("1"));
        assertFalse(TypeConvert.toBoolean("false"));
        assertFalse(TypeConvert.toBoolean("no"));
        assertFalse(TypeConvert.toBoolean("0"));
        assertNull(TypeConvert.toBoolean("abc"));
        assertEquals(Boolean.TRUE, TypeConvert.toBoolean(null, Boolean.TRUE));
    }

    @Test
    void testToBigInteger() {
        assertEquals(BigInteger.valueOf(123), TypeConvert.toBigInteger(123));
        assertEquals(new BigInteger("456"), TypeConvert.toBigInteger("456"));
        assertNull(TypeConvert.toBigInteger("abc"));
        assertEquals(BigInteger.valueOf(789), TypeConvert.toBigInteger(null, BigInteger.valueOf(789)));
    }

    @Test
    void testToBigDecimal() {
        assertEquals(BigDecimal.valueOf(1.23), TypeConvert.toBigDecimal(1.23));
        assertEquals(new BigDecimal("4.56"), TypeConvert.toBigDecimal("4.56"));
        assertNull(TypeConvert.toBigDecimal("abc"));
        assertEquals(BigDecimal.valueOf(7.89), TypeConvert.toBigDecimal(null, BigDecimal.valueOf(7.89)));
    }

    @Test
    void testToUtf8String() {
        assertEquals("hello", TypeConvert.toUtf8String("hello"));
        assertEquals("abc", TypeConvert.toUtf8String("abc".getBytes(Charset.forName("UTF-8"))));
        ByteBuffer buffer = ByteBuffer.wrap("xyz".getBytes(Charset.forName("UTF-8")));
        assertEquals("xyz", TypeConvert.toUtf8String(buffer));
    }

    @Test
    void testConvertCharset() {
        byte[] bytes = "test".getBytes(StandardCharsets.UTF_8);
        assertEquals("test", TypeConvert.convertCharset(bytes, "UTF-8"));
        assertEquals("test", TypeConvert.convertCharset(bytes, Charset.forName("UTF-8")));
        ByteBuffer buffer = ByteBuffer.wrap("data".getBytes(Charset.forName("UTF-8")));
        assertEquals("data", TypeConvert.convertCharset(buffer, Charset.forName("UTF-8")));
        
        buffer = ByteBuffer.wrap("data".getBytes(Charset.forName("UTF-8")));
        assertEquals("data", TypeConvert.convertCharset(buffer, "UTF-8"));
    }

    @Test
    void testToFullCharAndToHalfChar() {
        assertEquals("ABC123", TypeConvert.toFullChar("ABC123"));
        assertEquals("ABC123", TypeConvert.toHalfChar("ABC123"));
        Set<Character> notConvert = new HashSet<>();
        notConvert.add('A');
        assertTrue(TypeConvert.toFullChar("A", notConvert).startsWith("A"));
        notConvert.clear();
        notConvert.add('A');
        assertTrue(TypeConvert.toHalfChar("A", notConvert).startsWith("A"));
    }

    @Test
    void testDigitUppercase() {
        assertTrue(TypeConvert.digitUppercase(123.45).contains("元"));
        assertTrue(TypeConvert.digitUppercase(0).contains("零元整"));
        assertTrue(TypeConvert.digitUppercase(-100).startsWith("負"));
    }

    @Test
    void testPrivateConstructor() {

        assertThrows(IllegalAccessException.class, () -> {
            TypeConvert.class.getDeclaredConstructor().newInstance();
        });
    }

     @Test
    @DisplayName("mergeListStringToString: merge list with delimiter")
    void testMergeListStringToString() {
        List<String> list = Arrays.asList("a", "b", "c");
        assertEquals("a,b,c,", TypeConvert.mergeListStringToString(list, ","));
        assertEquals("a|b|c|", TypeConvert.mergeListStringToString(list, "|"));
        assertEquals("abc", TypeConvert.mergeListStringToString(list, ""));
    }

       @Test
    @DisplayName("arrayListToString: merge list to string")
    void testArrayListToString() {
        List<String> list = Arrays.asList("a", "b", "c");
        assertEquals("abc", TypeConvert.arrayListToString(list));
        assertEquals("", TypeConvert.arrayListToString(new ArrayList<>()));
    }

    @Test
    @DisplayName("objectToBlob and blobToObject: serialize and deserialize")
    void testObjectToBlobAndBlobToObject() throws SerialException, IOException, SQLException {
        String testString = "test";
        Blob blob = TypeConvert.objectToBlob(testString);
        assertNotNull(blob);
        Object obj = TypeConvert.blobToObject(blob);
        assertEquals(testString, obj);
    }

    @Test
    @DisplayName("stringArrayListToByte and ByteToStringArrayList: convert list to bytes and back")
    void testStringArrayListToByteAndBack() {
        List<String> list = Arrays.asList("line1", "line2", "line3");
        byte[] bytes = TypeConvert.stringArrayListToByte(list);
        assertNotNull(bytes);
        List<String> result = TypeConvert.byteToStringArrayList(bytes);

        assertTrue(StringUtils.equals("line1", result.get(0)));
        assertTrue(StringUtils.equals("line2", result.get(1)));
        assertTrue(StringUtils.equals("line3", result.get(2)));
    }

    @Test
    @DisplayName("objectToBase64String and base64StringToObject: serialize and deserialize")
    void testObjectToBase64StringAndBack() throws IOException, ClassNotFoundException {
        String testString = "base64Test";
        String base64 = TypeConvert.objectToBase64String(testString);
        assertNotNull(base64);
        Object obj = TypeConvert.base64StringToObject(base64);
        assertEquals(testString, obj);
    }

}


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言