你用過Hutool嗎?趕緊試試吧!真香!
前言
今天給大家介紹一個能夠幫助大家提升開發(fā)效率的開源工具包:hutool
。
Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關API的學習成本,提高工作效率,使Java擁有函數(shù)式語言般的優(yōu)雅,讓Java語言也可以“甜甜的”。
Hutool的設計思想是盡量減少重復的定義,讓項目中的util這個package盡量少,總的來說有如下的幾個思想:
- 方法優(yōu)先于對象
- 自動識別優(yōu)于用戶定義
- 便捷性與靈活性并存
- 適配與兼容
- 可選依賴原則
- 無侵入原則
Hutool是一個Java工具包類庫,對文件、流、加密解密、轉(zhuǎn)碼、正則、線程、XML等JDK方法進行封裝,組成各種Util工具類,可以幫助我們提升開發(fā)效率。
想要使用Hutool的功能,必須要先引入它的依賴,在項目的pom.xml文件中引入:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
即可引入Hutool包的相關依賴。
接下來,我們一起看看Hutool包含了哪些強大的功能。
1.Convert
在Java開發(fā)中我們要面對各種各樣的類型轉(zhuǎn)換問題,比如:數(shù)組轉(zhuǎn)換成字符串,日期轉(zhuǎn)換成字符串等。
我們需要手寫許多代碼,或者專門處理異常,比較麻煩。
而Hutool包專門提供了Convert類,我們使用它做類型轉(zhuǎn)換,使用起來非常方便。
數(shù)字轉(zhuǎn)換為字符串:
int a = 1;
//aStr為"1"
String aStr = Convert.toStr(a);
轉(zhuǎn)換為指定類型數(shù)組:
long[] b = {1,2,3,4,5};
//bStr為:"[1, 2, 3, 4, 5]"
String bStr = Convert.toStr(b);
轉(zhuǎn)換為指定類型數(shù)組:
String[] b = { "1", "2", "3", "4" };
//結(jié)果為Integer數(shù)組
Integer[] intArray = Convert.toIntArray(b);
long[] c = {1,2,3,4,5};
//結(jié)果為Integer數(shù)組
Integer[] intArray2 = Convert.toIntArray(c);
轉(zhuǎn)換為日期對象:
String a = "2017-05-06";
Date value = Convert.toDate(a);
轉(zhuǎn)換為集合
Object[] a = {"a", "你", "好", "", 1};
List<?> list = Convert.convert(List.class, a);
//從4.1.11開始可以這么用
List<?> list = Convert.toList(a);
2.DateUtil
Java本身對日期時間的支持有限,并且Date和Calendar對象的并存導致各種方法使用混亂和復雜。
通常情況下,我們需要使用SimpleDateFormat類,做時間和字符串類型的轉(zhuǎn)換。
其實Hutool包專門提供了DateUtil類,給我們做時間和日期類型轉(zhuǎn)換的。
(1) Date和Calendar相互轉(zhuǎn)換
//當前時間
Date date = DateUtil.date();
//當前時間
Date date2 = DateUtil.date(Calendar.getInstance());
(2)字符串轉(zhuǎn)日期
將字符串轉(zhuǎn)換成Date類型:
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);
自定義時間格式做類型轉(zhuǎn)換:
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");
(3)格式化日期輸出
String dateStr = "2017-03-01";
Date date = DateUtil.parse(dateStr);
//結(jié)果 2017/03/01
String format = DateUtil.format(date, "yyyy/MM/dd");
//常用格式的格式化,結(jié)果:2017-03-01
String formatDate = DateUtil.formatDate(date);
//結(jié)果:2017-03-01 00:00:00
String formatDateTime = DateUtil.formatDateTime(date);
//結(jié)果:00:00:00
String formatTime = DateUtil.formatTime(date);
(4)開始和結(jié)束時間
有的時候我們需要獲得每天的開始時間、結(jié)束時間,每月的開始和結(jié)束時間等等,DateUtil也提供了相關方法:
String dateStr = "2017-03-01 22:33:23";
Date date = DateUtil.parse(dateStr);
//一天的開始,結(jié)果:2017-03-01 00:00:00
Date beginOfDay = DateUtil.beginOfDay(date);
//一天的結(jié)束,結(jié)果:2017-03-01 23:59:59
Date endOfDay = DateUtil.endOfDay(date);
3.StrUtil
這個工具的用處類似于Apache Commons Lang中的StringUtil,常用的方法例如isBlank、isNotBlank、isEmpty、isNotEmpty。
(1)hasBlank方法
就是給定一些字符串,如果一旦有空的就返回true,常用于判斷好多字段是否有空的(例如web表單數(shù)據(jù))。
這兩個方法的區(qū)別是hasEmpty只判斷是否為null或者空字符串(""),hasBlank則會把不可見字符也算做空,isEmpty和isBlank同理。
(2)removePrefix方法
這兩個是去掉字符串的前綴后綴的,例如去個文件名的擴展名啥。
String fileName = StrUtil.removeSuffix("pretty_girl.jpg", ".jpg") //fileName -> pretty_girl
還有忽略大小寫的removePrefixIgnoreCase和removeSuffixIgnoreCase都比較實用。
(3)sub方法
不得不提一下這個方法,有人說String有了subString你還寫它干啥,我想說subString方法越界啥的都會報異常,而使用StrUtil的sub就不會報錯:
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)format方法
靈感來自slf4j,可以使用字符串模板代替字符串拼接。
String template = "{}愛{},就像老鼠愛大米";
String str = StrUtil.format(template, "我", "你"); //str -> 我愛你,就像老鼠愛大米
4.ReflectUtil
Java的反射機制,可以讓語言變得更加靈活,對對象的操作也更加“動態(tài)”,因此在某些情況下,反射可以做到事半功倍的效果。Hutool針對Java的反射機制做了工具化封裝,封裝包括:
- 獲取構(gòu)造方法
- 獲取字段
- 獲取字段值
- 獲取方法
- 執(zhí)行方法(對象方法和靜態(tài)方法)
(1)獲取某個類的所有方法
Method[] methods = ReflectUtil.getMethods(ExamInfoDict.class);
(2)獲取某個類的指定方法
Method method = ReflectUtil.getMethod(ExamInfoDict.class, "getId");
(3)構(gòu)造對象
ReflectUtil.newInstance(ExamInfoDict.class);
(4)執(zhí)行方法
class TestClass {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
TestClass testClass = new TestClass();
ReflectUtil.invoke(testClass, "setA", 10);
5.IdUtil
在分布式環(huán)境中,唯一ID生成應用十分廣泛,生成方法也多種多樣,Hutool針對一些常用生成策略做了簡單封裝。
唯一ID生成器的工具類,涵蓋了:
- UUID
- ObjectId(MongoDB)
- Snowflake(Twitter)
(1)UUID
UUID全稱通用唯一識別碼(universally unique identifier),JDK通過java.util.UUID提供了 Leach-Salz 變體的封裝。在Hutool中,生成一個UUID字符串方法如下:
//生成的UUID是帶-的字符串,類似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
String uuid = IdUtil.randomUUID();
//生成的是不帶-的字符串,類似于:b17f24ff026d40949c85a24f4f375d42
String simpleUUID = IdUtil.simpleUUID();
說明 Hutool重寫java.util.UUID的邏輯,對應類為cn.hutool.core.lang.UUID,使生成不帶-的UUID字符串不再需要做字符替換,性能提升一倍左右。
(2)ObjectId
ObjectId是MongoDB數(shù)據(jù)庫的一種唯一ID生成策略,是UUID version1的變種,詳細介紹可見:服務化框架-分布式Unique ID的生成方法一覽。
Hutool針對此封裝了cn.hutool.core.lang.ObjectId,快捷創(chuàng)建方法為:
//生成類似:5b9e306a4df4f8c54a39fb0c
String id = ObjectId.next();
//方法2:從Hutool-4.1.14開始提供
String id2 = IdUtil.objectId();
(3)Snowflake
分布式系統(tǒng)中,有一些需要使用全局唯一ID的場景,有些時候我們希望能使用一種簡單一些的ID,并且希望ID能夠按照時間有序生成。Twitter的Snowflake 算法就是這種生成器。
使用方法如下:
//參數(shù)1為終端ID
//參數(shù)2為數(shù)據(jù)中心ID
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id = snowflake.nextId();
//簡單使用
long id = IdUtil.getSnowflakeNextId();
String id = snowflake.getSnowflakeNextIdStr();
6.RandomUtil
RandomUtil主要針對JDK中Random對象做封裝,嚴格來說,Java產(chǎn)生的隨機數(shù)都是偽隨機數(shù),因此Hutool封裝后產(chǎn)生的隨機結(jié)果也是偽隨機結(jié)果。不過這種隨機結(jié)果對于大多數(shù)情況已經(jīng)夠用。
RandomUtil.randomInt 獲得指定范圍內(nèi)的隨機數(shù) 例如我們想產(chǎn)生一個[10, 100)的隨機數(shù),則:
int c = RandomUtil.randomInt(10, 100);
RandomUtil.randomBytes 隨機bytes,一般用于密碼或者salt生成
byte[] c = RandomUtil.randomBytes(10);
RandomUtil.randomEle 隨機獲得列表中的元素。
RandomUtil.randomEleSet 隨機獲得列表中的一定量的不重復元素,返回Set
Set<Integer> set = RandomUtil.randomEleSet(CollUtil.newArrayList(1, 2, 3, 4, 5, 6), 2);
7.BeanUtil
通常Java中對Bean的定義是包含setXXX和getXXX方法的對象,在Hutool中,采取一種簡單的判定Bean的方法:是否存在只有一個參數(shù)的setXXX方法。
(1)判斷是否為Bean對象
BeanUtil.isBean方法根據(jù)是否存在只有一個參數(shù)的setXXX方法或者public類型的字段來判定是否是一個Bean對象。這樣的判定方法主要目的是保證至少有一個setXXX方法用于屬性注入。
boolean isBean = BeanUtil.isBean(HashMap.class);//false
(2)Bean轉(zhuǎn)為Map
BeanUtil.beanToMap方法則是將一個Bean對象轉(zhuǎn)為Map對象。
SubPerson person = new SubPerson();
person.setAge(14);
person.setOpenid("11213232");
person.setName("測試A11");
person.setSubName("sub名字");
Map<String, Object> map = BeanUtil.beanToMap(person);
(3)Bean轉(zhuǎn)Bean
Bean之間的轉(zhuǎn)換主要是相同屬性的復制,因此方法名為copyProperties,此方法支持Bean和Map之間的字段復制。
BeanUtil.copyProperties方法同樣提供一個CopyOptions參數(shù)用于自定義屬性復制。
SubPerson p1 = new SubPerson();
p1.setSlow(true);
p1.setName("測試");
p1.setSubName("sub測試");
Map<String, Object> map = MapUtil.newHashMap();
BeanUtil.copyProperties(p1, map);
8.JSONUtil
JSONUtil是針對JSONObject和JSONArray的靜態(tài)快捷方法集合。
(1)JSON字符串創(chuàng)建
JSONUtil.toJsonStr可以將任意對象(Bean、Map、集合等)直接轉(zhuǎn)換為JSON字符串。如果對象是有序的Map等對象,則轉(zhuǎn)換后的JSON字符串也是有序的。
SortedMap<Object, Object> sortedMap = new TreeMap<Object, Object>() {
private static final long serialVersionUID = 1L;
{
put("attributes", "a");
put("b", "b");
put("c", "c");
}};
JSONUtil.toJsonStr(sortedMap);
結(jié)果:
{"attributes":"a","b":"b","c":"c"}
如果我們想獲得格式化后的JSON,則:
JSONUtil.toJsonPrettyStr(sortedMap);
結(jié)果:
{
"attributes": "a",
"b": "b",
"c": "c"
}
(2)JSON字符串解析
String html = "{\"name\":\"Something must have been changed since you leave\"}";
JSONObject jsonObject = JSONUtil.parseObj(html);
jsonObject.getStr("name");
(3)XML字符串轉(zhuǎn)換為JSON
String s = "<sfzh>123</sfzh><sfz>456</sfz><name>aa</name><gender>1</gender>";
JSONObject json = JSONUtil.parseFromXml(s);
json.get("sfzh");
json.get("name");
(4)JSON轉(zhuǎn)換為XML
final JSONObject put = JSONUtil.createObj()
.set("aaa", "你好")
.set("鍵2", "test");
// <aaa>你好</aaa><鍵2>test</鍵2>
final String s = JSONUtil.toXmlStr(put);
(5)JSON轉(zhuǎn)Bean
我們先定義兩個較為復雜的Bean(包含泛型)
@Data
public class ADT {
private List<String> BookingCode;
}
@Data
public class Price {
private List<List<ADT>> ADT;
}
String json = "{\"ADT\":[[{\"BookingCode\":[\"N\",\"N\"]}]]}";
Price price = JSONUtil.toBean(json, Price.class);
price.getADT().get(0).get(0).getBookingCode().get(0);
當然,上面只是列舉了Hutool的一部分功能,更多功能可以去它官網(wǎng):https://www.hutool.cn查看。
總體來說,Hutool目前封裝的這些工具類,確實非常好用,可以節(jié)省我們重復造輪子的時間,少寫很多代碼,幫助我們提升開發(fā)效率。