“黑铁时代”读者群里有个小伙伴感慨说,“Hutool 这款开源类库太厉害了,基本上该有该的工具类,它里面都有。”讲真的,我日常工做中也常常用 Hutool,它确实能够帮助咱们简化每一行代码,使 Java 拥有函数式语言般的优雅,让 Java 语言变得“甜甜的”。前端
可是呢,群里还有一部分小伙伴表示还不知道这个开源类库,第一次据说。因此我决定写一篇文章普及下,毕竟好的轮子值得推荐啊。java
Hutool 的做者在官网上说,Hutool 是 Hu+tool 的自造词(好像不用说,咱们也能猜获得),“Hu”用来致敬他的“前任”公司,“tool”就是工具的意思,谐音就有意思了,“糊涂”,寓意追求“万事都做糊涂观,无所谓失,无所谓得”(一个开源类库,上升到了哲学的高度,做者厉害了)。git
看了一下开发团队的一个成员介绍,一个 Java 后端工具的做者居然爱前端、爱数码,爱漂亮女,嗯嗯嗯,确实“可贵糊涂”(手动狗头)。程序员
就连向这个开源类库提交的 PR(pull request)规范都很是“病态化”(哈哈哈):github
废话就说到这,来吧,实操走起!后端
Maven 项目只须要在 pom.xml 文件中添加如下依赖便可。数组
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
复制代码
Hutool 的设计思想是尽可能减小重复的定义,让项目中的 util 包尽可能少。一个好的轮子能够在很大程度上避免“复制粘贴”,从而节省咱们开发人员对项目中公用类库和公用工具方法的封装时间。同时呢,成熟的开源库也能够最大限度的避免封装不完善带来的 bug。缓存
就像做者在官网上说的那样:微信
有了 Hutool 之后呢,引入 Hutool -> 直接
SecureUtil.md5()
markdown
Hutool 对不只对 JDK 底层的文件、流、加密解密、转码、正则、线程、XML等作了封装,还提供了如下这些组件:
很是多,很是全面,鉴于此,我只挑选一些我喜欢的来介绍下(偷偷地告诉你,我就是想偷懒)。
类型转换在 Java 开发中很常见,尤为是从 HttpRequest 中获取参数的时候,前端传递的是整形,但后端只能先获取到字符串,而后再调用 parseXXX()
方法进行转换,还要加上判空,很繁琐。
Hutool 的 Convert 类能够简化这个操做,能够将任意可能的类型转换为指定类型,同时第二个参数 defaultValue 可用于在转换失败时返回一个默认值。
String param = "10";
int paramInt = Convert.toInt(param);
int paramIntDefault = Convert.toInt(param, 0);
复制代码
把字符串转换成日期:
String dateStr = "2020年09月29日";
Date date = Convert.toDate(dateStr);
复制代码
把字符串转成 Unicode:
String unicodeStr = "沉默王二";
String unicode = Convert.strToUnicode(unicodeStr);
复制代码
JDK 自带的 Date 和 Calendar 不太好用,Hutool 封装的 DateUtil 用起来就舒服多了!
获取当前日期:
Date date = DateUtil.date();
复制代码
DateUtil.date()
返回的实际上是 DateTime,它继承自 Date 对象,重写了 toString()
方法,返回 yyyy-MM-dd HH:mm:ss
格式的字符串。
有些小伙伴是否是想看看我写这篇文章的时间,输出一下给你们看看:
System.out.println(date);// 2020-09-29 04:28:02
复制代码
字符串转日期:
String dateStr = "2020-09-29";
Date date = DateUtil.parse(dateStr);
复制代码
DateUtil.parse()
会自动识别一些经常使用的格式,好比说:
还能够识别带中文的:
格式化时间差:
String dateStr1 = "2020-09-29 22:33:23";
Date date1 = DateUtil.parse(dateStr1);
String dateStr2 = "2020-10-01 23:34:27";
Date date2 = DateUtil.parse(dateStr2);
long betweenDay = DateUtil.between(date1, date2, DateUnit.MS);
// 输出:2天1小时1分4秒
String formatBetween = DateUtil.formatBetween(betweenDay, BetweenFormater.Level.SECOND);
复制代码
星座和属相:
// 射手座
String zodiac = DateUtil.getZodiac(Month.DECEMBER.getValue(), 10);
// 蛇
String chineseZodiac = DateUtil.getChineseZodiac(1989);
复制代码
IO 操做包括读和写,应用的场景主要包括网络操做和文件操做,原生的 Java 类库区分字符流和字节流,字节流 InputStream 和 OutputStream 就有不少不少种,使用起来让人头皮发麻。
Hutool 封装了流操做工具类 IoUtil、文件读写操做工具类 FileUtil、文件类型判断工具类 FileTypeUtil 等等。
BufferedInputStream in = FileUtil.getInputStream("hutool/origin.txt");
BufferedOutputStream out = FileUtil.getOutputStream("hutool/to.txt");
long copySize = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE);
复制代码
在 IO 操做中,文件的操做相对来讲是比较复杂的,但使用频率也很高,几乎全部的项目中都躺着一个叫 FileUtil 或者 FileUtils 的工具类。Hutool 的 FileUtil 类包含如下几类操做:
顺带说说 classpath。
在实际编码当中,咱们一般须要从某些文件里面读取一些数据,好比配置文件、文本文件、图片等等,那这些文件一般放在什么位置呢?
放在项目结构图中的 resources 目录下,当项目编译后,会出如今 classes 目录下。对应磁盘上的目录以下图所示:
当咱们要读取文件的时候,我是不建议使用绝对路径的,由于操做系统不同的话,文件的路径标识符也是不同的。最好使用相对路径。
假设在 src/resources
下放了一个文件 origin.txt,文件的路径参数以下所示:
FileUtil.getInputStream("origin.txt")
复制代码
假设文件放在 src/resources/hutool
目录下,则路径参数改成:
FileUtil.getInputStream("hutool/origin.txt")
复制代码
Hutool 封装的字符串工具类 StrUtil 和 Apache Commons Lang 包中的 StringUtils 相似,做者认为优点在于 Str 比 String 短,尽管我不以为。不过,我却是挺喜欢其中的一个方法的:
String template = "{},一枚沉默但有趣的程序员,喜欢他的文章的话,请微信搜索{}";
String str = StrUtil.format(template, "沉默王二", "沉默王二");
// 沉默王二,一枚沉默但有趣的程序员,喜欢他的文章的话,请微信搜索沉默王二
复制代码
反射机制可让 Java 变得更加灵活,所以在某些状况下,反射能够作到事半功倍的效果。Hutool 封装的反射工具 ReflectUtil 包括:
package com.itwanger.hutool.reflect;
import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/** * @author 微信搜「沉默王二」,回复关键字 PDF */
public class ReflectDemo {
private int id;
public ReflectDemo() {
System.out.println("构造方法");
}
public void print() {
System.out.println("我是沉默王二");
}
public static void main(String[] args) throws IllegalAccessException {
// 构建对象
ReflectDemo reflectDemo = ReflectUtil.newInstance(ReflectDemo.class);
// 获取构造方法
Constructor[] constructors = ReflectUtil.getConstructors(ReflectDemo.class);
for (Constructor constructor : constructors) {
System.out.println(constructor.getName());
}
// 获取字段
Field field = ReflectUtil.getField(ReflectDemo.class, "id");
field.setInt(reflectDemo, 10);
// 获取字段值
System.out.println(ReflectUtil.getFieldValue(reflectDemo, field));
// 获取全部方法
Method[] methods = ReflectUtil.getMethods(ReflectDemo.class);
for (Method m : methods) {
System.out.println(m.getName());
}
// 获取指定方法
Method method = ReflectUtil.getMethod(ReflectDemo.class, "print");
System.out.println(method.getName());
// 执行方法
ReflectUtil.invoke(reflectDemo, "print");
}
}
复制代码
在 Java 中,对文件、文件夹打包压缩是一件很繁琐的事情,Hutool 封装的 ZipUtil 针对 java.util.zip 包作了优化,可使用一个方法搞定压缩和解压,而且自动处理文件和目录的问题,再也不须要用户判断,大大简化的压缩解压的复杂度。
ZipUtil.zip("hutool", "hutool.zip");
File unzip = ZipUtil.unzip("hutool.zip", "hutoolzip");
复制代码
Hutool 封装的 IdcardUtil 能够用来对身份证进行验证,支持大陆 15 位、18 位身份证,港澳台 10 位身份证。
String ID_18 = "321083197812162119";
String ID_15 = "150102880730303";
boolean valid = IdcardUtil.isValidCard(ID_18);
boolean valid15 = IdcardUtil.isValidCard(ID_15);
复制代码
Java 中的 HashMap 是强类型的,而 Hutool 封装的 Dict 对键的类型要求没那么严格。
Dict dict = Dict.create()
.set("age", 18)
.set("name", "沉默王二")
.set("birthday", DateTime.now());
int age = dict.getInt("age");
String name = dict.getStr("name");
复制代码
本地编码的过程当中,常常须要使用 System.out
打印结果,可是每每一些复杂的对象不支持直接打印,好比说数组,须要调用 Arrays.toString
。Hutool 封装的 Console 类借鉴了 JavaScript 中的 console.log()
,使得打印变成了一个很是便捷的方式。
/** * @author 微信搜「沉默王二」,回复关键字 PDF */
public class ConsoleDemo {
public static void main(String[] args) {
// 打印字符串
Console.log("沉默王二,一枚有趣的程序员");
// 打印字符串模板
Console.log("洛阳是{}朝古都",13);
int [] ints = {1,2,3,4};
// 打印数组
Console.log(ints);
}
}
复制代码
作 Web 开发的时候,后端一般须要对表单提交过来的数据进行验证。Hutool 封装的 Validator 能够进行不少有效的条件验证:
Validator.isEmail("沉默王二");
Validator.isMobile("itwanger.com");
复制代码
Guava 中提供了一种特殊的 Map 结构,叫作 BiMap,实现了一种双向查找的功能,能够根据 key 查找 value,也能够根据 value 查找 key,Hutool 也提供这种 Map 结构。
BiMap<String, String> biMap = new BiMap<>(new HashMap<>());
biMap.put("wanger", "沉默王二");
biMap.put("wangsan", "沉默王三");
// get value by key
biMap.get("wanger");
biMap.get("wangsan");
// get key by value
biMap.getKey("沉默王二");
biMap.getKey("沉默王三");
复制代码
在实际的开发工做中,其实我更倾向于使用 Guava 的 BiMap,而不是 Hutool 的。这里提一下,主要是我发现了 Hutool 在线文档上的一处错误,提了个 issue(从中能够看出我一颗一丝不苟的心和一双清澈明亮的大眼睛啊)。
Hutool 封装的 ImgUtil 能够对图片进行缩放、裁剪、转为黑白、加水印等操做。
缩放图片:
ImgUtil.scale(
FileUtil.file("hutool/wangsan.jpg"),
FileUtil.file("hutool/wangsan_small.jpg"),
0.5f
);
复制代码
裁剪图片:
ImgUtil.cut(
FileUtil.file("hutool/wangsan.jpg"),
FileUtil.file("hutool/wangsan_cut.jpg"),
new Rectangle(200, 200, 100, 100)
);
复制代码
添加水印:
ImgUtil.pressText(//
FileUtil.file("hutool/wangsan.jpg"),
FileUtil.file("hutool/wangsan_logo.jpg"),
"沉默王二", Color.WHITE,
new Font("黑体", Font.BOLD, 100),
0,
0,
0.8f
);
复制代码
趁机让你们欣赏一下二哥帅气的真容。
众所周知,Java 中普遍应用的配置文件 Properties 存在一个特别大的诟病:不支持中文。每次使用时,若是想存放中文字符,就必须借助 IDE 相关插件才能转为 Unicode 符号,而这种反人类的符号在命令行下根本无法看。
因而,Hutool 的 Setting 运用而生。Setting 除了兼容 Properties 文件格式外,还提供了一些特有功能,这些功能包括:
先整个配置文件 example.setting,内容以下:
name=沉默王二
age=18
复制代码
再来读取和更新配置文件:
/** * @author 微信搜「沉默王二」,回复关键字 PDF */
public class SettingDemo {
private final static String SETTING = "hutool/example.setting";
public static void main(String[] args) {
// 初始化 Setting
Setting setting = new Setting(SETTING);
// 读取
setting.getStr("name", "沉默王二");
// 在配置文件变动时自动加载
setting.autoLoad(true);
// 经过代码方式增长键值对
setting.set("birthday", "2020年09月29日");
setting.store(SETTING);
}
}
复制代码
Hutool 封装的日志工厂 LogFactory 兼容了各大日志框架,使用起来也很是简便。
/** * @author 微信搜「沉默王二」,回复关键字 PDF */
public class LogDemo {
private static final Log log = LogFactory.get();
public static void main(String[] args) {
log.debug("可贵糊涂");
}
}
复制代码
先经过 LogFactory.get()
自动识别引入的日志框架,从而建立对应日志框架的门面 Log 对象,而后调用 debug()
、info()
等方法输出日志。
若是不想建立 Log 对象的话,可使用 StaticLog,顾名思义,一个提供了静态方法的日志类。
StaticLog.info("爽啊 {}.", "沉默王二的文章");
复制代码
CacheUtil 是 Hutool 封装的建立缓存的快捷工具类,能够建立不一样的缓存对象:
Cache<String, String> fifoCache = CacheUtil.newFIFOCache(3);
fifoCache.put("key1", "沉默王一");
fifoCache.put("key2", "沉默王二");
fifoCache.put("key3", "沉默王三");
fifoCache.put("key4", "沉默王四");
// 大小为 3,因此 key3 放入后 key1 被清除
String value1 = fifoCache.get("key1");
复制代码
Cache<String, String> lfuCache = CacheUtil.newLFUCache(3);
lfuCache.put("key1", "沉默王一");
// 使用次数+1
lfuCache.get("key1");
lfuCache.put("key2", "沉默王二");
lfuCache.put("key3", "沉默王三");
lfuCache.put("key4", "沉默王四");
// 因为缓存容量只有 3,当加入第 4 个元素的时候,最少使用的将被移除(2,3被移除)
String value2 = lfuCache.get("key2");
String value3 = lfuCache.get("key3");
复制代码
Cache<String, String> lruCache = CacheUtil.newLRUCache(3);
lruCache.put("key1", "沉默王一");
lruCache.put("key2", "沉默王二");
lruCache.put("key3", "沉默王三");
// 使用时间近了
lruCache.get("key1");
lruCache.put("key4", "沉默王四");
// 因为缓存容量只有 3,当加入第 4 个元素的时候,最久使用的将被移除(2)
String value2 = lruCache.get("key2");
System.out.println(value2);
复制代码
加密分为三种:
Hutool 针对这三种状况都作了封装:
快速加密工具类 SecureUtil 有如下这些方法:
1)对称加密
2)非对称加密
3)摘要加密
只写一个简单的例子做为参考:
/** * @author 微信搜「沉默王二」,回复关键字 PDF */
public class SecureUtilDemo {
static AES aes = SecureUtil.aes();
public static void main(String[] args) {
String encry = aes.encryptHex("沉默王二");
System.out.println(encry);
String oo = aes.decryptStr(encry);
System.out.println(oo);
}
}
复制代码
Hutool 中的类库还有不少,尤为是一些对第三方类库的进一步封装,好比邮件工具 MailUtil,二维码工具 QrCodeUtil,Emoji 工具 EmojiUtil,小伙伴们能够参考 Hutool 的官方文档:www.hutool.cn/
项目源码地址:github.com/looly/hutoo…
PS:须要 Java 书单的话,我在 GitHub 上发现了一个宝藏项目,里面的书单可谓应有尽有。须要的小伙伴能够按需自取,地址以下所示:
最后,平常求个赞吧,满满的干货,我先干为敬,你随意😑