用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

这几天在微信公众号看到有号主推荐一个Java工具类库,当时没有在意,觉得已经有Java的common包了,还有Guava类库,已经够用了。但是今天又来看了一遍,觉得这个类库别有一番风味。

Github上关于Hutool介绍:

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以"甜甜的"。

Hutool中的工具方法来自于每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;

Hutool是项目中"util"包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。

为什么Hutool会诞生,Hutool的优势在哪,我们来看看官方介绍。

Hutool的目标是使用一个工具方法代替一段复杂代码,从而最大限度的避免“复制粘贴”代码的问题,彻底改变我们写代码的方式。

以计算MD5为例:

【以前】打开搜索引擎 -> 搜“Java MD5加密” -> 打开某篇博客-> 复制粘贴 -> 改改好用

【现在】引入Hutool -> SecureUtil.md5()

Hutool的存在就是为了减少代码搜索成本,避免网络上参差不齐的代码出现导致的bug。

官方文档网址:

https://www.hutool.cn/docs/#/

Hutool主要组件:

模块介绍hutool-aopJDK动态代理封装,提供非IOC下的切面支持hutool-bloomFilter布隆过滤,提供一些Hash算法的布隆过滤hutool-cache简单缓存实现hutool-core核心,包括Bean操作、日期、各种Util等hutool-cron定时任务模块,提供类Crontab表达式的定时任务hutool-crypto加密解密模块,提供对称、非对称和摘要算法封装hutool-dbJDBC封装后的数据操作,基于ActiveRecord思想hutool-dfa基于DFA模型的多关键字查找hutool-extra扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)hutool-http基于HttpUrlConnection的Http客户端封装hutool-log自动识别日志实现的日志门面hutool-script脚本执行封装,例如Javascripthutool-setting功能更强大的Setting配置文件和Properties封装hutool-system系统参数调用封装(JVM信息等)hutool-jsonJSON实现hutool-captcha图片验证码实现hutool-poi针对POI中Excel和Word的封装hutool-socket基于Java的NIO和AIO的Socket封装

Maven导入

<dependency>    <groupId>cn.hutool</groupId>    <artifactId>hutool-all</artifactId>    <version>5.4.2</version></dependency>

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

来介绍几个我用过的方法。

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

转换成String

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);

将int转换String,只要Convert.toStr(a)。不用去try catch了。

转换为指定类型数组

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);

将String转换成Date。跟以前的DateUtils工具类比,这个比较简单吧。

进制的转换

String转换成16进制

String a = "我是一个小小的可爱的字符串";//结果:"e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2"String hex = Convert.toHex(a, CharsetUtil.CHARSET_UTF_8);

16进制转换成String

String hex = "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2";//结果为:"我是一个小小的可爱的字符串"String raw = Convert.hexStrToStr(hex, CharsetUtil.CHARSET_UTF_8);//注意:在4.1.11之后hexStrToStr将改名为hexToStrString raw = Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8);

编码转换

在接收表单的时候,我们常常被中文乱码所困扰,其实大多数原因是使用了不正确的编码方式解码了数据。于是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);

金额大小转换

double a = 67556.32;//结果为:"陆万柒仟伍佰伍拾陆元叁角贰分"String digitUppercase = Convert.digitToChinese(a);

这个功能不错。

Date、long、Calendar之间的相互转换

//当前时间Date date = DateUtil.date();//当前时间Date date2 = DateUtil.date(Calendar.getInstance());//当前时间,可以用于将时间戳转换成日期Date date3 = DateUtil.date(System.currentTimeMillis());//当前时间字符串,格式:yyyy-MM-dd HH:mm:ssString now = DateUtil.now();//当前日期字符串,格式:yyyy-MM-ddString today= DateUtil.today();

当然也可以自定义格式转换

String dateStr = "2017-03-01";Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");//结果 2017/03/01String format = DateUtil.format(date, "yyyy/MM/dd");//常用格式的格式化,结果:2017-03-01String formatDate = DateUtil.formatDate(date);//结果:2017-03-01 00:00:00String formatDateTime = DateUtil.formatDateTime(date);//结果:00:00:00String formatTime = DateUtil.formatTime(date);

格式化的时间差

有时候需要易读的时间差,比如XX天XX小时XX分XX秒

//Level.MINUTE表示精确到分String formatBetween = DateUtil.formatBetween(between, Level.MINUTE);//输出:31天1小时Console.log(formatBetween);

计时器

用于计算某段代码运行时间

TimeInterval timer = DateUtil.timer();//---------------------------------//-------这是执行过程//---------------------------------timer.interval();//花费毫秒数timer.intervalRestart();//返回花费时间,并重置开始时间timer.intervalMinute();//花费分钟数

星座和属相

这个功能有趣

// "摩羯座"String zodiac = DateUtil.getZodiac(Month.JANUARY.getValue(), 19);// "狗"String chineseZodiac = DateUtil.getChineseZodiac(1994);

还可以计算年龄,是否闰年等功能

//年龄DateUtil.ageOfNow("1990-01-30");//是否闰年DateUtil.isLeapYear(2017);

农历日期

还可以获取农历日期哦

//通过农历构建ChineseDate chineseDate = new ChineseDate(1992,12,14);//通过公历构建ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("1993-01-06"));

具体方法如下

// 一月date.getChineseMonth();// 正月date.getChineseMonthName();// 初一date.getChineseDay();// 庚子date.getCyclical();// 生肖:鼠date.getChineseZodiac();// 传统节日(部分支持,逗号分隔):春节date.getFestivals();// 庚子鼠年 正月初一date.toString();

LocalDateTime工具-LocalDateTimeUtil

针对JDK8 日期API的封装,此工具类的功能包括LocalDateTime和LocalDate的解析、格式化、转换等操作。

文件拷贝

将A文件拷贝到B文件

BufferedInputStream in = FileUtil.getInputStream("d:/test.txt");BufferedOutputStream out = FileUtil.getOutputStream("d:/test2.txt");long copySize = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE);

文件监听-WatchMonitor

很多时候我们需要监听一个文件的变化或者目录的变动,包括文件的创建、修改、删除,以及目录下文件的创建、修改和删除,在JDK7前我们只能靠轮询方式遍历目录或者定时检查文件的修改事件,这样效率非常低,性能也很差。因此在JDK7中引入了WatchService。不过考虑到其API并不友好,于是Hutool便针对其做了简化封装,使监听更简单,也提供了更好的功能。

WatchMonitor提供的事件有:

  • ENTRY_MODIFY 文件修改的事件
  • ENTRY_CREATE 文件或目录创建的事件
  • ENTRY_DELETE 文件或目录删除的事件
  • OVERFLOW 丢失的事件

具体使用可以看看官方使用文档。

还有更多的文件读取功能。

丰富的工具类

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

我来列举几个工具的使用

TypeUtil

主要用来:

  1. 获取方法的参数和返回值类型(包括Type和Class)
  2. 获取泛型参数类型(包括对象的泛型参数或集合元素的泛型类型)

获取方法参数类型

Method method = ReflectUtil.getMethod(TestClass.class, "intTest", Integer.class);Type type = TypeUtil.getParamType(method, 0);// 结果:Integer.class

获取方法返回值的类型

Method method = ReflectUtil.getMethod(TestClass.class, "getList");Type type = TypeUtil.getReturnType(method);// 结果:java.util.List<java.lang.String>

身份证工具-IdcardUtil

IdcardUtil现在支持大陆15位、18位身份证,港澳台10位身份证。

工具中主要的方法包括:

  1. isValidCard 验证身份证是否合法
  2. convert15To18 身份证15位转18位
  3. getBirthByIdCard 获取生日
  4. getAgeByIdCard 获取年龄
  5. getYearByIdCard 获取生日年
  6. getMonthByIdCard 获取生日月
  7. getDayByIdCard 获取生日天
  8. getGenderByIdCard 获取性别
  9. getProvinceByIdCard 获取省份

代码举例

String ID_18 = "321083197812162119";String ID_15 = "150102880730303";//是否有效boolean valid = IdcardUtil.isValidCard(ID_18);boolean valid15 = IdcardUtil.isValidCard(ID_15);//转换String convert15To18 = IdcardUtil.convert15To18(ID_15);Assert.assertEquals(convert15To18, "150102198807303035");//年龄DateTime date = DateUtil.parse("2017-04-10");int age = IdcardUtil.getAgeByIdCard(ID_18, date);Assert.assertEquals(age, 38);int age2 = IdcardUtil.getAgeByIdCard(ID_15, date);Assert.assertEquals(age2, 28);//生日String birth = IdcardUtil.getBirthByIdCard(ID_18);Assert.assertEquals(birth, "19781216");String birth2 = IdcardUtil.getBirthByIdCard(ID_15);Assert.assertEquals(birth2, "19880730");//省份String province = IdcardUtil.getProvinceByIdCard(ID_18);Assert.assertEquals(province, "江苏");String province2 = IdcardUtil.getProvinceByIdCard(ID_15);Assert.assertEquals(province2, "内蒙古");

BeanUtil工具

可以将Map填充到Bean里面

@Datapublic class Person{    private String name;    private int age;}HashMap<String, Object> map = CollUtil.newHashMap();map.put("name", "Joe");map.put("age", 12);SubPerson person = BeanUtil.fillBeanWithMap(map, new Person(), false);

还可以将Bean转换成Map

// Bean转换为MapMap<String, Object> map = BeanUtil.beanToMap(person);// 返回"sub名字"map.get("SubName")

忽略null值的拷贝

BeanUtil.copyProperties(studentVo,studentDto,true, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));

还可以自定义属性的拷贝。

关于Bean与Bean之间的拷贝。还可以看看我的这篇文章:

几种实体拷贝方式实战

有界优先队列-BoundedPriorityQueue

举个例子。我有一个用户表,这个表根据用户名被Hash到不同的数据库实例上,我要找出这些用户中最热门的5个,怎么做?我是这么做的:

  1. 在每个数据库实例上找出最热门的5个
  2. 将每个数据库实例上的这5条数据按照热门程度排序,最后取出前5条

这个过程看似简单,但是你应用服务器上的代码要写不少。首先需要Query N个列表,加入到一个新列表中,排序,再取前5。这个过程不但代码繁琐,而且牵涉到多个列表,非常浪费空间。

于是,BoundedPriorityQueue应运而生。

示例代码如下:

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

数学相关-MathUtil

这个有关于排列、组合的计算

  1. 排列
  • arrangementCount 计算排列数
  • arrangementSelect 排列选择(从列表中选择n个排列)
  1. 组合
  • combinationCount 计算组合数,即C(n, m) = n!/((n-m)! * m!)
  • combinationSelect 组合选择(从列表中选择n个组合)

高并发测试-ConcurrencyTester

这个功能不错,可以用于并发测试。

ConcurrencyTester tester = ThreadUtil.concurrencyTest(100, () -> {    // 测试的逻辑内容    long delay = RandomUtil.randomLong(100, 1000);    ThreadUtil.sleep(delay);    Console.log("{} test finished, delay: {}", Thread.currentThread().getName(), delay);});// 获取总的执行时间,单位毫秒Console.log(tester.getInterval());

缓存工具类

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

还有一些缓存工具类。相比传统的集合,Hutool缓存类更丰富,可以设置存活时间,还有不同的存活方式。

加密工具类

用了Java工具类库-Hutool,我的代码清爽了很多(java hutools)

加密工具也可以了解下。

定时任务

这个功能非常不错,Java中定时任务使用的最多的就是quartz了,但是这个框架太过庞大,而且我也不需要用到这么多东西,使用方法也是比较复杂(当然可以使用Spring的注解完成)。

用过Linux的crontab的人都知道,使用其定时的表达式可以非常灵活的定义定时任务的时间以及频率(Linux的crontab精确到分,而Quartz的精确到秒,不过对我来说精确到分已经够用了,精确到秒的可以使用Timer可以搞定),然后就是crontab的那个迷人的配置文件,可以把定时任务很清晰的罗列出来,这个我也是比较喜欢的。于是Hutool-cron诞生。

来看看如何使用

对于Maven项目,首先在src/main/resources/config下放入cron.setting文件(默认是这个路径的这个文件),然后在文件中放入定时规则,规则如下:

# 我是注释[com.company.aaa.job]TestJob.run = */10 * * * *TestJob2.run = */10 * * * *Copy to clipboardErrorCopied

中括号表示分组,也表示需要执行的类或对象方法所在包的名字,这种写法有利于区分不同业务的定时任务。

TestJob.run表示需要执行的类名和方法名(通过反射调用,不支持Spring和任何框架的依赖注入),*/10 * * * *表示定时任务表达式,此处表示每10分钟执行一次,以上配置等同于:

com.company.aaa.job.TestJob.run = */10 * * * *com.company.aaa.job.TestJob2.run = */10 * * * *

然后启动;

CronUtil.start();

这个启动方法加在需要触发的地方,比如随系统启动,可以加在main方法中。

当然也可以自定义定时任务

CronUtil.schedule("*/2 * * * * *", new Task() {    @Override    public void execute() {        Console.log("Task excuted.");    }});// 支持秒级别定时任务CronUtil.setMatchSecond(true);CronUtil.start();

怎么样,这款工具对你有没有帮助呢。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。