Hutool(三)

136 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

五、Convert类型转换

1. 痛点

在Java开发中我们要面对各种各样的类型转换问题,尤其是从命令行获取的用户参数、从HttpRequest获取的Parameter等等,这些参数类型多种多样,我们怎么去转换他们呢?常用的办法是先整成String,然后调用XXX.parseXXX方法,还要承受转换失败的风险,不得不加一层try catch,这个小小的过程混迹在业务代码中会显得非常难看和臃肿。

2. Convert类

Convert类可以说是一个工具方法类,里面封装了针对Java常见类型的转换,用于简化类型转换。Convert类中大部分方法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultValue用于在转换失败时返回一个默认值。

3. 如何使用

1. 转换为字符串

int a = 1;
//aStr为"1"
String aStr = Convert.toStr(a);

long[] b = {1,2,3,4,5};
//bStr为:"[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);

2. 转换为指定类型数组

String[] b = { "1", "2", "3", "4" };
//结果为Integer数组
Integer[] intArray = Convert.toIntArray(b);

long[] c = {1,2,3,4,5};
//结果为Integer数组
Integer[] intArray2 = Convert.toIntArray(c);

3. 转换为日期对象

String str = "2012-12-12";
// 以前这样将字符串转为日期
Date parse = new SimpleDateFormat("yyyy-MM-dd").parse(str);

// 现在这样将字符串转为日期
Date date = Convert.toDate(str);
System.out.println(date);
String str1 = "2012/12/12";
Date date1 = Convert.toDate(str1);
System.out.println(date1);

4.转换为集合

Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
//从4.1.11开始可以这么用
List<?> lists = Convert.toList(a);

5. 普通字符串与16进制字符串之间的转换

在很多加密解密,以及中文字符串传输(比如表单提交)的时候,会用到16进制转换,就是Hex转换,为此Hutool中专门封装了HexUtil工具类,考虑到16进制转换也是转换的一部分,因此将其方法也放在Convert类中,便于理解和查找,使用同样非常简单:

// 普通字符串转为16进制字符串
String a = "我是一个小小的可爱的字符串";
//结果:"e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2"
String hex = Convert.toHex(a, CharsetUtil.CHARSET_UTF_8);
// 将16进制(Hex)字符串转为普通字符串
String hex = "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2";
//结果为:"我是一个小小的可爱的字符串"
String raw = Convert.hexStrToStr(hex, CharsetUtil.CHARSET_UTF_8);

//注意:在4.1.11之后hexStrToStr将改名为hexToStr
String raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);

因为字符串牵涉到编码问题,因此必须传入编码对象,此处使用UTF-8编码。 toHex方法同样支持传入byte[],同样也可以使用hexToBytes方法将16进制转为byte[]。

6. Unicode和字符串转换

与16进制类似,Convert类同样可以在字符串和Unicode之间轻松转换:

String a = "我是一个小小的可爱的字符串";

//结果为:"\\u6211\\u662f\\u4e00\\u4e2a\\u5c0f\\u5c0f\\u7684\\u53ef\\u7231\\u7684\\u5b57\\u7b26\\u4e32"    
String unicode = Convert.strToUnicode(a);

//结果为:"我是一个小小的可爱的字符串"
String raw = Convert.unicodeToStr(unicode);

7. 编码之间的转换

在接收表单的时候,我们常常被中文乱码所困扰,其实大多数原因是使用了不正确的编码方式解码了数据。于是Convert.convertCharset方法便派上用场了,它可以把乱码转为正确的编码方式:

String a = "我不是乱码";
//转换后result为乱码
// 将utf-8编码转为ISO_8859_1编码
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
// 将ISO_8859_1编码转为utf-8编码
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);

注意 经过测试,UTF-8编码后用GBK解码再用GBK编码后用UTF-8解码会存在某些中文转换失败的问题。

8. 时间单位转换

Convert.convertTime方法主要用于转换时长单位,比如一个很大的毫秒,我想获得这个毫秒数对应多少分:

long a = 4535345;

//结果为:75
// 将毫秒转为秒
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);

9. 金额大小写转换

面对财务类需求,Convert.digitToChinese将金钱数转换为大写形式:

double x = 123.13;
// 结果为:壹佰贰拾叁元壹角叁分
String s = Convert.digitToChinese(x);

注意 转换为大写只能精确到分(小数点儿后两位),之后的数字会被忽略。

10. 数字转换

  1. 数字转为英文表达

    // ONE HUNDRED AND TWENTY THREE ONLY
    String format = Convert.numberToWord(123);
    
  2. 数字简化

    // 1.2k
    String format1 = Convert.numberToSimple(1200, false);
    
  3. 数字转中文

    数字转中文方法中,只保留两位小数

    // 一万零八百八十九点七二
    String f1 = Convert.numberToChinese(10889.72356, false);
    
    // 使用金额大写
    // 壹万贰仟陆佰伍拾叁
    String f1 = Convert.numberToChinese(12653, true);
    
  4. 数字中文表示转换为数字

    // 1012
    String f1 = Convert.numberToChinese("一千零一十二");
    

11. 原始类和包装类转换

有的时候,我们需要将包装类和原始类相互转换(比如Integer.class 和 int.class),这时候我们可以:

//去包装
Class<?> wrapClass = Integer.class;

//结果为:int.class
Class<?> unWraped = Convert.unWrap(wrapClass);

//包装
Class<?> primitiveClass = long.class;

//结果为:Long.class
Class<?> wraped = Convert.wrap(primitiveClass);