hutool(字符串工具-StrUtil与类型转换工具类-Convert)
Posted madleep
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hutool(字符串工具-StrUtil与类型转换工具类-Convert)相关的知识,希望对你有一定的参考价值。
由来
这个工具的用处类似于Apache Commons Lang中的StringUtil,之所以使用StrUtil而不是使用StringUtil是因为前者更短,而且Str这个简写我想已经深入人心了,大家都知道是字符串的意思。常用的方法例如isBlank、isNotBlank、isEmpty、isNotEmpty这些我就不做介绍了,判断字符串是否为空,下面我说几个比较好用的功能。
方法
1. hasBlank、hasEmpty方法
就是给定一些字符串,如果一旦有空的就返回true,常用于判断好多字段是否有空的(例如web表单数据)。
这两个方法的区别是hasEmpty只判断是否为null或者空字符串(“”),hasBlank则会把不可见字符也算做空,isEmpty和isBlank同理。
2. removePrefix、removeSuffix方法
这两个是去掉字符串的前缀后缀的,例如去个文件名的扩展名啥。
String fileName = StrUtil.removeSuffix("pretty_girl.jpg", ".jpg") //fileName -> pretty_girl
还有忽略大小写的removePrefixIgnoreCase和removeSuffixIgnoreCase都比较实用。
3. sub方法
不得不提一下这个方法,有人说String有了subString你还写它干啥,我想说subString方法越界啥的都会报异常,你还得自己判断,难受死了,我把各种情况判断都加进来了,而且index的位置还支持负数哦,-1表示最后一个字符(这个思想来自于Python,如果学过Python的应该会很喜欢的),还有就是如果不小心把第一个位置和第二个位置搞反了,也会自动修正(例如想截取第4个和第2个字符之间的部分也是可以的哦~) 举个栗子
String str = "abcdefgh";
String strSub1 = StrUtil.sub(str, 2, 3); //strSub1 -> c
String strSub2 = StrUtil.sub(str, 2, -3); //strSub2 -> cde
String strSub3 = StrUtil.sub(str, 3, 2); //strSub2 -> c
4. str、bytes方法
好吧,我承认把String.getByte(String charsetName)方法封装在这里了,原生的String.getByte()这个方法太坑了,使用系统编码,经常会有人跳进来导致乱码问题,所以我就加了这两个方法强制指定字符集了,包了个try抛出一个运行时异常,省的我得在我业务代码里处理那个恶心的UnsupportedEncodingException。
5. format方法
我会告诉你这是我最引以为豪的方法吗?灵感来自slf4j,可以使用字符串模板代替字符串拼接,我也自己实现了一个,而且变量的标识符都一样,神马叫无缝兼容~~来,上栗子(吃多了上火吧……)
String template = "爱,就像老鼠爱大米";
String str = StrUtil.format(template, "我", "你"); //str -> 我爱你,就像老鼠爱大米
参数我定义成了Object类型,如果传别的类型的也可以,会自动调用toString()方法的。
6. 定义的一些常量
为了方便,我定义了一些比较常见的字符串常量在里面,像点、空串、换行符等等,还有html中的一些转义字符。
痛点
在Java开发中我们要面对各种各样的类型转换问题,尤其是从命令行获取的用户参数、从HttpRequest获取的Parameter等等,这些参数类型多种多样,我们怎么去转换他们呢?常用的办法是先整成String,然后调用XXX.parseXXX方法,还要承受转换失败的风险,不得不加一层try catch,这个小小的过程混迹在业务代码中会显得非常难看和臃肿。
Convert类
Convert类可以说是一个工具方法类,里面封装了针对Java常见类型的转换,用于简化类型转换。Convert类中大部分方法为toXXX,参数为Object,可以实现将任意可能的类型转换为指定类型。同时支持第二个参数defaultValue用于在转换失败时返回一个默认值。
Java常见类型转换
转换为字符串:
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);
转换为指定类型数组:
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);
转换为日期对象:
String a = "2017-05-06";
Date value = Convert.toDate(a);
转换为集合
Object[] a = "a", "你", "好", "", 1;
List<?> list = Convert.convert(List.class, a);
//从4.1.11开始可以这么用
List<?> list = Convert.toList(a);
其它类型转换
标准类型
通过Convert.convert(Class, Object)方法可以将任意类型转换为指定类型,Hutool中预定义了许多类型转换,例如转换为URI、URL、Calendar等等,这些类型的转换都依托于ConverterRegistry类。通过这个类和Converter接口,我们可以自定义一些类型转换。详细的使用请参阅“自定义类型转换”一节。
泛型类型
通过convert(TypeReference reference, Object value)方法,自行new一个TypeReference对象可以对嵌套泛型进行类型转换。例如,我们想转换一个对象为List类型,此时传入的标准Class就无法满足要求,此时我们可以这样:
Object[] a = "a", "你", "好", "", 1 ;
List<String> list = Convert.convert(new TypeReference<List<String>>() , a);
通过TypeReference实例化后制定泛型类型,即可转换对象为我们想要的目标类型。
半角和全角转换
在很多文本的统一化中这两个方法非常有用,主要对标点符号的全角半角转换。
半角转全角:
String a = "123456789";
//结果为:"123456789"
String sbc = Convert.toSBC(a);
全角转半角:
String a = "123456789";
//结果为"123456789"
String dbc = Convert.toDBC(a);
16进制(Hex)
在很多加密解密,以及中文字符串传输(比如表单提交)的时候,会用到16进制转换,就是Hex转换,为此Hutool中专门封装了HexUtil工具类,考虑到16进制转换也是转换的一部分,因此将其方法也放在Convert类中,便于理解和查找,使用同样非常简单:
转为16进制(Hex)字符串
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[]
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);
很熟悉吧?如果你在properties文件中写过中文,你会明白这个方法的重要性。
编码转换
在接收表单的时候,我们常常被中文乱码所困扰,其实大多数原因是使用了不正确的编码方式解码了数据。于是Convert.convertCharset方法便派上用场了,它可以把乱码转为正确的编码方式:
String a = "我不是乱码";
//转换后result为乱码
String result = Convert.convertCharset(a, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
String raw = Convert.convertCharset(result, CharsetUtil.ISO_8859_1, "UTF-8");
Assert.assertEquals(raw, a);
注意 经过测试,UTF-8编码后用GBK解码再用GBK编码后用UTF-8解码会存在某些中文转换失败的问题。
时间单位转换
Convert.convertTime方法主要用于转换时长单位,比如一个很大的毫秒,我想获得这个毫秒数对应多少分:
long a = 4535345;
//结果为:75
long minutes = Convert.convertTime(a, TimeUnit.MILLISECONDS, TimeUnit.MINUTES);
金额大小写转换
面对财务类需求,Convert.digitToChinese将金钱数转换为大写形式:
double a = 67556.32;
//结果为:"陆万柒仟伍佰伍拾陆元叁角贰分"
String digitUppercase = Convert.digitToChinese(a);
注意 转换为大写只能精确到分(小数点儿后两位),之后的数字会被忽略。
数字转换
数字转为英文表达
// ONE HUNDRED AND CENTS TWENTY THREE ONLY
String format = Convert.numberToWord(100.23);
数字简化
// 1.2k
String format1 = Convert.numberToSimple(1200, false);
数字转中文
数字转中文方法中,只保留两位小数
// 一万零八百八十九点七二
String f1 = Convert.numberToChinese(10889.72356, false);
// 使用金额大写
// 壹万贰仟陆佰伍拾叁
String f1 = Convert.numberToChinese(12653, true);
数字中文表示转换为数字
// 1012
String f1 = Convert.numberToChinese("一千零一十二");
原始类和包装类转换
有的时候,我们需要将包装类和原始类相互转换(比如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);
2hutool实战:DateUtil-常用的时间类型转换
技术活,该赏
关注+一键三连(点赞,评论,收藏)再看,养成好习惯
用途:常用的时间类型转换
使用场景
常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换
项目引用
此博文的依据:hutool-5.6.5版本源码
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.6.5</version>
</dependency>
方法摘要
方法 | 描述 |
---|---|
cn.hutool.core.date.DateUtil.dateNew(java.util.Date) |
根据已有{@link Date} 产生新的{@link DateTime}对象
|
cn.hutool.core.date.DateUtil.date(long) |
Long类型时间转为{@link DateTime}<br> 只支持毫秒级别时间戳,如果需要秒级别时间戳,请自行×1000
|
cn.hutool.core.date.DateUtil.date(java.util.Calendar) |
{@link Calendar}类型时间转为{@link DateTime}<br> 始终根据已有{@link Calendar} 产生新的{@link DateTime}对象
|
cn.hutool.core.date.DateUtil.date(java.time.temporal.TemporalAccessor) |
{@link TemporalAccessor}类型时间转为{@link DateTime}<br> 始终根据已有{@link TemporalAccessor} 产生新的{@link DateTime}对象
|
方法明细
方法名称:cn.hutool.core.date.DateUtil.date(java.util.Date)
方法描述
{@link Date}类型时间转为{@link DateTime}<br>
如果date本身为DateTime对象,则返回强转后的对象,否则新建一个DateTime对象
支持版本及以上
3.0.7
参数描述:
参数名 | 描述 |
---|---|
Date date |
date Long类型Date(Unix时间戳)
|
返回值:
时间对象
参考案例:
//如果date本身为DateTime对象,则返回强转后的对象,否则新建一个DateTime对象
Date date1 = DateUtil.date(new Date());
Assert.assertNotNull(date1);
Date date2 = DateUtil.date(DateUtil.date());
Assert.assertNotNull(date2);
源码解析:
链接:待补充
方法明细
方法名称:cn.hutool.core.date.DateUtil.dateNew(java.util.Date)
方法描述
根据已有{@link Date} 产生新的{@link DateTime}对象
支持版本及以上
4.3.1
参数描述:
参数名 | 描述 |
---|---|
Date date |
date Date对象
|
返回值:
{@link DateTime}对象
参考案例:
//根据已有{@link Date} 产生新的{@link DateTime}对象
Date nowDate = new Date();
System.out.println(nowDate.toString());
Date date5 = DateUtil.dateNew(new Date());
System.out.println(date5.toString());
Assert.assertNotNull(date5);
源码解析:
链接:待补充
方法明细
方法名称:cn.hutool.core.date.DateUtil.date(long)
方法描述
Long类型时间转为{@link DateTime}<br>
只支持毫秒级别时间戳,如果需要秒级别时间戳,请自行×1000
支持版本及以上
参数描述:
参数名 | 描述 |
---|---|
long date |
date Long类型Date(Unix时间戳)
|
返回值:
时间对象
参考案例:
//只支持毫秒级别时间戳,如果需要秒级别时间戳,请自行×1000
Date date6 = DateUtil.date(System.currentTimeMillis());
System.out.println(date6);
Assert.assertNotNull(date6);
源码解析:
链接:待补充
方法明细
方法名称:cn.hutool.core.date.DateUtil.date(java.util.Calendar)
方法描述
{@link Calendar}类型时间转为{@link DateTime}<br>
始终根据已有{@link Calendar} 产生新的{@link DateTime}对象
支持版本及以上
参数描述:
参数名 | 描述 |
---|---|
Calendar calendar |
calendar {@link Calendar}
|
返回值:
时间对象
参考案例:
//DateTime 和 Calendar的转换
DateTime date7 = DateUtil.date();
Calendar calendar = date7.toCalendar();
DateUtil.date(calendar);
Assert.assertNotNull(date7);
源码解析:
链接:待补充
方法明细
方法名称:cn.hutool.core.date.DateUtil.date(java.time.temporal.TemporalAccessor)
方法描述
{@link TemporalAccessor}类型时间转为{@link DateTime}<br>
始终根据已有{@link TemporalAccessor} 产生新的{@link DateTime}对象
支持版本及以上
5.0.0
参数描述:
参数名 | 描述 |
---|---|
TemporalAccessor temporalAccessor |
temporalAccessor {@link TemporalAccessor},常用子类: {@link LocalDateTime}、 LocalDate
|
返回值:
时间对象
参考案例:
//TemporalAccessor类型时间转换为DateTime
String str = "31-Aug-2020";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.US);
//temporalAccessor {@link TemporalAccessor},常用子类: {@link LocalDateTime}、 LocalDate
LocalDateTime localDateTime = LocalDate.parse(str, dtf).atStartOfDay();
Date date1 = DateUtil.date(localDateTime);
System.out.println(date1);
Assert.assertNotNull(date1);
源码解析:
链接:待补充
以上是关于hutool(字符串工具-StrUtil与类型转换工具类-Convert)的主要内容,如果未能解决你的问题,请参考以下文章
Hutool工具:使用Hutool工具进行Convert类型转换
2hutool源码分析:DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换
2hutool源码分析:DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换