Java開發常用類庫之Hutool詳解
Hutool是一個小而全的Java工具類庫,通過靜態方法封裝,降低相關API的學習成本,提高工作效率,使Java擁有函數式語言般的優雅,讓Java語言也可以“甜甜的”。
Hutool中的工具方法來自每個用戶的精雕細琢,它涵蓋了Java開發底層代碼中的方方面面,它既是大型項目開發中解決小問題的利器,也是小型項目中的效率擔當;
Hutool是項目中“util”包友好的替代,它節省了開發人員對項目中公用類和公用工具方法的封裝時間,使開發專注于業務,同時可以最大限度的避免封裝不完善帶來的bug。
Hutool名稱的由來Hutool = Hu + tool,是原公司項目底層代碼剝離后的開源庫,“Hu”是公司名稱的表示,tool表示工具。Hutool諧音“糊涂”,一方面簡潔易懂,一方面寓意“難得糊涂”。
Hutool如何改變我們的coding方式Hutool的目標是使用一個工具方法代替一段復雜代碼,從而最大限度的避免“復制粘貼”代碼的問題,徹底改變我們寫代碼的方式。
以計算MD5為例:
【以前】打開搜索引擎 -> 搜“Java MD5加密” -> 打開某篇博客-> 復制粘貼 -> 改改好用 【現在】引入Hutool -> SecureUtil.md5()Hutool的存在就是為了減少代碼搜索成本,避免網絡上參差不齊的代碼出現導致的bug。
上述摘自HuTool官網
安裝在Maven項目中在項目的pom.xml的dependencies中加入以下內容:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.8</version></dependency>
非Maven項目中
點擊以下任一鏈接,下載hutool-all-X.X.X.jar即可:
Maven中央庫1
Maven中央庫2
注意 Hutool 5.x支持JDK8+,對Android平臺沒有測試,不能保證所有工具類或工具方法可用。 如果你的項目使用JDK7,請使用Hutool 4.x版本
常用方法
本文的所有代碼均已上傳GitHub,HuTool學習
類型轉換類型轉換的工具類為Convert
轉為字符串
// int類型轉換int aInt = 1023;String aStr = Convert.toStr(aInt);// aStr結果為1023System.out.println(aStr);// 數組進行轉換int[] bArray = {1,2,3,4,5};String bStr = Convert.toStr(bArray);// bStr結果為[1, 2, 3, 4, 5]System.out.println(bStr);
轉為指定類型數組
String[] strArray = { '1', '0', '2', '3' };//結果為Integer數組Integer[] intArray = Convert.toIntArray(strArray);System.out.println(Convert.toStr(intArray));Integer[] intArray2 = {1,0,2,3};//結果為String數組String[] strArray2 = Convert.toStrArray(intArray2);System.out.println(Convert.toStr(strArray2));
轉換為Date日期對象
String date = '2000-10-23';//結果為Date日期對象Date value = Convert.toDate(date);System.out.println(value);
轉化為List集合
Object[] objectArray = {'lolly1023','lolly',1023};List<?> list = Convert.convert(List.class, objectArray);System.out.println(list);// 4.1.11版本之后可使用toListList<?> list2 = Convert.toList(objectArray);System.out.println(list2);日期時間
日期時間的工具類為DateUtil
多種獲取日期的方式
// 獲取當前時間的Date對象Date nowDate = DateUtil.date();System.out.println(nowDate);// 使用Calendar獲取當前時間的Date對象Date nowDate2 = DateUtil.date(Calendar.getInstance());System.out.println(nowDate2);// 使用當前時間戳獲取當前時間的Date對象Date nowDate3 = DateUtil.date(System.currentTimeMillis());System.out.println(nowDate3);// 使用工具類獲取當前時間的字符串,格式為:yyyy-MM-dd HH:mm:ssString nowDateStr = DateUtil.now();System.out.println(nowDateStr);// 使用工具類獲取當前時間的字符串,格式為:yyyy-MM-ddString todayDateStr= DateUtil.today();System.out.println(todayDateStr);
輸出樣式為:
2021-02-19 21:04:122021-02-19 21:04:122021-02-19 21:04:122021-02-19 21:04:122021-02-19
字符串轉換為Date對象字符串轉為Date對象使用到了DateUtil工具類中的parse方法,該方法會自動識別一些日期的常用格式,例如:
yyyy-MM-dd HH:mm:ss.SSS yyyy-MM-dd HH:mm:ss yyyy-MM-dd HH:mm yyyy-MM-dd HH:mm:ss// 字符串轉為Date對象 String dateStr = '2000-10-23 12:30';Date date = DateUtil.parse(dateStr);// 輸出2000-10-23 12:30:00System.out.println(date);// 也可以在轉的時候指定格式Date date2 = DateUtil.parse(dateStr,'yyyy-MM-dd');// 輸出2000-10-23 00:00:00System.out.println(date2);
格式化Date對象
//格式化Date日期對象Date date4 = DateUtil.date();String format = DateUtil.format(date4, 'yyyy年MM月dd日');// 輸出為2021年02月19日System.out.println(format);String formatDate = DateUtil.formatDate(date4);// 常用格式化,輸出為2021-02-19System.out.println(formatDate);String formatDateTime = DateUtil.formatDateTime(date4);// 精確到秒,結果為2021-02-19 21:16:09System.out.println(formatDateTime);String formatTime = DateUtil.formatTime(date4);// 只保留時分秒,結果為21:16:09System.out.println(formatTime);
獲取Date對象的年月日
// 獲取Date對象的年月日Date date5 = DateUtil.date();// 獲取年,結果為2021System.out.println(DateUtil.year(date5));// 獲取月,結果為1(從0開始計數,0則為一月)System.out.println(DateUtil.month(date5));// 獲取日(在本年)System.out.println(DateUtil.dayOfYear(date5));// 獲取日(在本月)System.out.println(DateUtil.dayOfMonth(date5));// 獲取日(在本周)System.out.println(DateUtil.dayOfWeek(date5));
開始和結束日期
用于計算開始時間和結束時間,有每天的,每月的,等等
Date date3 = DateUtil.date();//一天的開始,結果:2021-02-19 00:00:00Date beginOfDay = DateUtil.beginOfDay(date3);System.out.println(beginOfDay);//一天的結束,結果:2021-02-19 23:59:59Date endOfDay = DateUtil.endOfDay(date3);System.out.println(endOfDay);//一月的開始,結果:2021-02-01 00:00:00Date beginOfMonth = DateUtil.beginOfMonth(date3);System.out.println(beginOfMonth);//一月的結束,結果:2021-02-28 23:59:59Date endOfMonth = DateUtil.endOfMonth(date3);System.out.println(endOfMonth);
日期時間的偏移
對日期的減少或者添加,可以對時分秒天周月等進行更改
String dateStr2 = '2000-10-23 12:30';Date date6 = DateUtil.parse(dateStr2);// 偏移10天DateTime newDate = DateUtil.offsetDay(date, 10);// 結果為2000-11-02 12:30:00System.out.println(newDate);// 偏移-10天DateTime newDate2 = DateUtil.offsetDay(date, -10);// 結果為2000-10-13 12:30:00System.out.println(newDate2);/**常用的偏移還有 * 月份 :DateUtil.offsetMonth(newDate2, offset) * 周:DateUtil.offsetWeek(newDate2, offset) */// 對比這種偏移,還有一種較簡單的偏移方法//昨天System.out.println(DateUtil.yesterday());//明天System.out.println(DateUtil.tomorrow());//上周System.out.println(DateUtil.lastWeek());//下周System.out.println(DateUtil.nextWeek());//上個月System.out.println(DateUtil.lastMonth());//下個月System.out.println(DateUtil.nextMonth());
日期時間差
用于計算兩個日期直接的時間差
String dateStr3 = '2000-10-23 12:30:00';Date date7 = DateUtil.parse(dateStr3);Date date8 = DateUtil.date();// 計算2000-10-23距今多久:7424天long betweenDay = DateUtil.between(date7, date8, DateUnit.DAY);System.out.println(betweenDay);
計時器
TimeInterval timer = DateUtil.timer();try {// 模擬耗時操作Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}//花費毫秒數System.out.println(timer.interval());//返回花費時間,并重置開始時間System.out.println(timer.intervalRestart());//花費分鐘數System.out.println(timer.intervalMinute());
星座與屬相
這個功能還是挺出乎意料的,沒想到還有這種
// '天秤座'String zodiac = DateUtil.getZodiac(Month.OCTOBER.getValue(), 23);System.out.println(zodiac);// '龍'String chineseZodiac = DateUtil.getChineseZodiac(2000);System.out.println(chineseZodiac);
年齡與閏年判斷
不得不說,這個工具類小玩意還挺多
//年齡System.out.println(DateUtil.ageOfNow('2000-10-23'));//是否閏年System.out.println(DateUtil.isLeapYear(2000));IO流相關
文件的拷貝
// 文件的拷貝BufferedInputStream in = FileUtil.getInputStream('d:/桌面/HuTool學習.md');BufferedOutputStream out = FileUtil.getOutputStream('d:/桌面/HuTool學習復制.md');long copySize = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE);// 拷貝文件的大小System.out.println(copySize);System.out.println('拷貝成功');in.close();out.close();
文件類型判斷
用于文件類型的判斷,返回值為文件的類型
File file = FileUtil.file('d:/桌面/HuTool學習.md');String type = FileTypeUtil.getType(file);//輸出的是文件的格式Console.log(type);
文件監聽
在以前,我們需要監聽文件的變化:創建修改刪除等,需要進行遍歷來定時檢查文件,效率很低,性能很差,所以有了這個工具類。監聽指定事件
File file2 = FileUtil.file('example.properties');//這里只監聽文件或目錄的修改事件WatchMonitor watchMonitor = WatchMonitor.create(file2, WatchMonitor.ENTRY_MODIFY);watchMonitor.setWatcher(new Watcher(){ @Override public void onCreate(WatchEvent<?> event, Path currentPath) { Object obj = event.context(); Console.log('創建:{}-> {}', currentPath, obj); } @Override public void onModify(WatchEvent<?> event, Path currentPath) { Object obj = event.context(); Console.log('修改:{}-> {}', currentPath, obj); } @Override public void onDelete(WatchEvent<?> event, Path currentPath) { Object obj = event.context(); Console.log('刪除:{}-> {}', currentPath, obj); } @Override public void onOverflow(WatchEvent<?> event, Path currentPath) { Object obj = event.context(); Console.log('Overflow:{}-> {}', currentPath, obj); }});//設置監聽目錄的最大深入,目錄層級大于制定層級的變更將不被監聽,默認只監聽當前層級目錄watchMonitor.setMaxDepth(3);//啟動監聽watchMonitor.start();
監聽全部事件
WatchMonitor.createAll(file, new SimpleWatcher(){ @Override public void onModify(WatchEvent<?> event, Path currentPath) { Console.log('EVENT modify'); }}).start();
文件的讀取
//默認UTF-8編碼,可以在構造中傳入第二個參數做為編碼FileReader fileReader = new FileReader('d:/桌面/HuTool測試.txt');String result = fileReader.readString();System.out.println(result);
文件的寫入
FileWriter writer = new FileWriter('d:/桌面/HuTool測試.txt');writer.write('添加文本',true);
文件追加
主要用于類似日志這種(此類只有在寫入文件的時候打開文件,寫入結束之后,此類不需要關閉)
File file = new File('d:/桌面/HuTool測試.txt');FileAppender appender = new FileAppender(file, 16, true);appender.append('lolly1023');appender.append('追加');appender.append('成功');appender.flush();appender.toString();
文件跟隨
有時候需要啟動線程來“監控”文件的變化,類似于Linux下的tail -f命令
Tailer tailer = new Tailer(FileUtil.file('d:/桌面/test.log'), Tailer.CONSOLE_HANDLER, 2);tailer.start();
實時打印文件變化的類
/** * 命令行打印的行處理器 * * @author looly * @since 4.5.2 */public static class ConsoleLineHandler implements LineHandler { @Override public void handle(String line) { Console.log(line); }}
該方法會阻塞線程
文件名與擴展名
獲取文件名
File file = FileUtil.file('d:/桌面/HuTool學習.md');// HuTool學習.mdString name = FileNameUtil.getName(file);System.out.println(name);
單獨獲取主文件名與擴展名
File file1 = FileUtil.file('d:/桌面/HuTool學習.md');// 'HuTool學習'String name1 = FileNameUtil.mainName(file1);System.out.println(name1);// 'md'String name2 = FileNameUtil.extName(file1);System.out.println(name2);工具類
字符串工具
判斷是否為空
給定指定字符串,如果是空,則返回true,使用到hasBlank和hasEmpty方法。hasEmpty只判斷是否為null或者是空字符串,hasBlank會把不可見的字符也算為空。
String nullStr = null;// trueSystem.out.println(StrUtil.hasBlank(nullStr));// trueSystem.out.println(StrUtil.hasEmpty(nullStr));
刪除前后綴
removePrefix為刪除字符串前綴,removeSuffix為刪除字符串后綴,經常用于去文件擴展名。
String fileName = StrUtil.removeSuffix('HuTool學習.md', '.md'); // HuTool學習System.out.println(fileName);String fileName1 = StrUtil.removePrefix('HuTool學習.md', 'HuTool學習.'); // mdSystem.out.println(fileName1);
截取字符串
在String中就有截取字符串的方法,但是時常會越界,在這個工具類中,該方法會自動判斷,支持負數,(與python相同),第二個位置與第一個位置搞反了的話,也會自動識別更改。
String str = 'lolly1023';String strSub1 = StrUtil.sub(str, 0, 5); // lollySystem.out.println(strSub1);String strSub2 = StrUtil.sub(str, 0, -4);// lollySystem.out.println(strSub2);String strSub3 = StrUtil.sub(str, 5, 0);// lollySystem.out.println(strSub3);
格式化字符串
使用{}進行占位即可,然后使用format方法進行格式化
// 使用{}占位String template = '{}+{}=2';// 1+1=2String str1 = StrUtil.format(template, '1', '1'); System.out.println(str1);
16進制工具
16進制的轉換
String str = '測試16進制轉換';String hex = HexUtil.encodeHexStr(str, CharsetUtil.CHARSET_UTF_8);// e6b58be8af953136e8bf9be588b6e8bdace68da2System.out.println(hex);String decodedStr = HexUtil.decodeHexStr(hex);// 測試16進制轉換,解碼后與str相同System.out.println(decodedStr);
URL工具
標準化URL鏈接
對于不帶http://頭的地址做簡單補全。
String url = 'http://www.hutool.cn//aaa/bbb';// 結果為:http://www.hutool.cn/aaa/bbbString normalize = URLUtil.normalize(url);System.out.println(normalize);url = 'http://www.hutool.cn//aaa/bbb?a=1&b=2';// 結果為:http://www.hutool.cn/aaa/bbb?a=1&b=2normalize = URLUtil.normalize(url);System.out.println(normalize);
XML工具
讀取XML
讀取XML分為兩個方法:
XmlUtil.readXML 讀取XML文件 XmlUtil.parseXml 解析XML字符串為Document對象寫XML
XmlUtil.toStr 將XML文檔轉換為String
XmlUtil.toFile 將XML文檔寫入到文件
創建XML
XmlUtil.createXml 創建XML文檔, 創建的XML默認是utf8編碼,修改編碼的過程是在toStr和toFile方法里,既XML在轉為文本的時候才定義編碼。
XML操作
通過以下工具方法,可以完成基本的節點讀取操作。
XmlUtil.cleanInvalid 除XML文本中的無效字符
XmlUtil.getElements 根據節點名獲得子節點列表
XmlUtil.getElement 根據節點名獲得第一個子節點
XmlUtil.elementText 根據節點名獲得第一個子節點
XmlUtil.transElements 將NodeList轉換為Element列表
XML與對象轉換
writeObjectAsXml 將可序列化的對象轉換為XML寫入文件,已經存在的文件將被覆蓋。
readObjectFromXml 從XML中讀取對象。
注意 這兩個方法嚴重依賴JDK的XMLEncoder和XMLDecoder,生成和解析必須成對存在(遵循固定格式),普通的XML轉Bean會報錯。
Xpath操作
更多Xpath操作:點擊此處舉例xml文件
<?xml version='1.0' encoding='utf-8'?><returnsms> <returnstatus>Success(成功)</returnstatus> <message>ok</message> <remainpoint>1490</remainpoint> <taskID>885</taskID> <successCounts>1</successCounts> </returnsms>
java代碼
File xmlFile = new File('/Study/HuToolTest/src/main/java/com/rj/bd/HuToolTest/UTilTest/URLUtil/Test.xml');Document docResult=XmlUtil.readXML(xmlFile);Object value = XmlUtil.getByXPath('//returnsms/message', docResult, XPathConstants.STRING);// okSystem.out.println(value.toString());
對象工具 兩個對象是否相等
需要滿足:
obj1 == null && obj2 == null
obj1.equals(obj2)
才會返回true
String string1 = '1';Integer integer1 = 1;// falseSystem.out.println(ObjectUtil.equal(string1, integer1));
計算對象長度
其實本質就是調用不同對象的計算長度方法,支持的類型有:
CharSequence Collection Map Iterator Enumeration ArrayList<Integer> list = new ArrayList<Integer>();// 0System.out.println(ObjectUtil.length(list));
判斷是否包含元素
即為判斷對象中是否包含元素
List<Integer> list1 = new ArrayList<Integer>();list1.add(0);// trueSystem.out.println(ObjectUtil.contains(list1, 0));
判斷是否為空
List<Integer> list2 = new ArrayList<Integer>();// falseSystem.out.println(ObjectUtil.isNull(list2));// trueSystem.out.println(ObjectUtil.isNotNull(list2));
克隆
ObjectUtil.clone克隆對象,如果對象實現Cloneable接口,調用其clone方法,如果實現Serializable接口,執行深度克隆,否則返回null。
ObjectUtil.cloneIfPossible 返回克隆后的對象,如果克隆失敗,返回原對象
ObjectUtil.cloneByStream 序列化后拷貝流的方式克隆,對象必須實現Serializable接口
序列化與反序列化 serialize 序列化,調用JDK序列化unserialize 反序列化,調用JDK 判斷基本類型
如果該對象是基本類型,則返回true,反之返回false。
int i = 0;// trueSystem.out.println(ObjectUtil.isBasicType(i));
反射 獲取某類的全部方法
// 獲取類中的全部方法Method[] methods = ReflectUtil.getMethods(Test.class);
獲取某類的某個方法
// 獲取類中的某個方法Method method = ReflectUtil.getMethod(Test.class, 'getID');
獲取某類的構造方法
// 獲取某類的構造方法ReflectUtil.newInstance(Test.class);
執行方法
public class TestClass {public String print(String string) {return string;}}
測試類
TestClass testClass = new TestClass();// lolly1023ReflectUtil.invoke(testClass, 'print', 'lolly1023');
剪切板工具 獲取剪切板內容及修改剪切板內容
// 獲取系統剪切板內容Clipboard copy = ClipboardUtil.getClipboard();// 設置剪切板內容,圖片的話使用setImageClipboardUtil.setStr('123');// 獲取剪切板內容:123,圖片的話使用getImageSystem.out.println(ClipboardUtil.getStr());命令行工具
通過Java代碼執行命令行命令,在Wubdows下是cmd,在Linux下是shell命令
執行命令
// cmd下輸入ipconfig為網卡信息String str = RuntimeUtil.execForStr('ipconfig');// 輸出正常,為網卡信息System.out.println(str);
數字工具 加減乘除
NumberUtil.add 針對double類型做加法
NumberUtil.sub 針對double類型做減法
NumberUtil.mul 針對double類型做乘法
NumberUtil.div 針對double類型做除法,并提供重載方法用于規定除不盡的情況下保留小數位數和舍棄方式。
以上的方法都會將double轉為BigDecimal,解決了精確問題。
保留小數
double te1=123456.123456;double te2=123456.123456;// 第二個參數為保留幾位小數// 123456.1Console.log(NumberUtil.round(te1,1));// 123456.123Console.log(NumberUtil.round(te2,3));
四舍五入
double te3=123456.123456;double te4=123456.128456;// 第二個參數為保留幾位小數//123456.12Console.log(NumberUtil.roundStr(te3,2));//123456.13Console.log(NumberUtil.roundStr(te4,2));
格式化
long c=299792458;//光速String format = NumberUtil.decimalFormat(',###', c);//299,792,458System.out.println(format);
常用的格式化方式
0 -> 取一位整數
0.00 -> 取一位整數和兩位小數
00.000 -> 取兩位整數和三位小數
# -> 取所有整數部分
#.##% -> 以百分比方式計數,并取兩位小數
#.#####E0 -> 顯示為科學計數法,并取五位小數,### -> 每三位以逗號進行分隔,例如:299,792,458
光速大小為每秒,###米 -> 將格式嵌入文本
更多格式化操作,點擊處此
是否為數字
NumberUtil.isNumber 是否為數字
NumberUtil.isInteger 是否為整數
NumberUtil.isDouble 是否為浮點數
NumberUtil.isPrimes 是否為質數 隨機數
第一個參數為最小值,第二個參數為最大值,第三個參數為長度。
// 生成隨機數,用int類型數組承載int[] array = NumberUtil.generateRandomNumber(0, 10, 8);System.out.println(Convert.toStr(array));// 生成隨機數,用Integer類型數組承載Integer[] array2 = NumberUtil.generateBySet(0, 10, 8);System.out.println(Convert.toStr(array2));
有序整數列表
生成一個有序的int類型數組
// 第一個參數為起點,第二個參數為終點int[] array3 = NumberUtil.range(2, 5);// [2, 3, 4, 5]System.out.println(Convert.toStr(array3));
其它
NumberUtil.factorial 階乘
NumberUtil.sqrt 平方根
NumberUtil.divisor 最大公約數
NumberUtil.multiple 最小公倍數
NumberUtil.getBinaryStr 獲得數字對應的二進制字符串
NumberUtil.binaryToInt 二進制轉int
NumberUtil.binaryToLong 二進制轉long
NumberUtil.compare 比較兩個值的大小
NumberUtil.toStr 數字轉字符串,自動并去除尾小數點兒后多余的0
數組工具判斷是否為空
int[] a = {};int[] b = null;// 判斷空// trueSystem.out.println(ArrayUtil.isEmpty(a));// trueSystem.out.println(ArrayUtil.isEmpty(b));//判斷非空// falseSystem.out.println(ArrayUtil.isNotEmpty(a));
新建泛型數組
該方法支持泛型返回值
String[] newArray = ArrayUtil.newArray(String.class, 3);
調整大小
ArrayUtil.resize(newArray, 4);
合并數組
int[] c = {1,2,3};int[] d = {4,5,6};int[] e = ArrayUtil.addAll(c,d);// [1, 2, 3, 4, 5, 6]System.out.println(Convert.toStr(e));
克隆
泛型數組調用原生克隆
Integer[] b = {1,2,3};Integer[] cloneB = ArrayUtil.clone(b);Assert.assertArrayEquals(b, cloneB);
非泛型數組(原始類型數組)調用第二種重載方法
int[] a = {1,2,3};int[] clone = ArrayUtil.clone(a);Assert.assertArrayEquals(a, clone);
有序列表生成
int[] array = ArrayUtil.range(0,10);// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]System.out.println(Convert.toStr(array));
拆分數組
byte[] array2 = {1,1,1,1,2,2,2,2};byte[][] array3 = ArrayUtil.split(array2, 4);// [[1, 1, 1, 1], [2, 2, 2, 2]]System.out.println(Convert.toStr(array3));
過濾
舉例,過濾數組,保留偶數
Integer[] a = {1,2,3,4,5,6};Integer[] filter = ArrayUtil.filter(a, new Editor<Integer>(){ @Override public Integer edit(Integer t) { return (t % 2 == 0) ? t : null; }});Assert.assertArrayEquals(filter, new Integer[]{2,4,6});
兩個數組生成map
此方法在python中為zip()函數。第一個數組為key,第二個數組對應為value。
String[] keys = {'w', 'e', 'r', 'f'};Integer[] values = {1,0,2,3};Map<String, Integer> map = ArrayUtil.zip(keys, values, true);// {w=1, e=0, r=2, f=3}System.out.println(Convert.toStr(map));
是否包含元素
int[] f = {1,2,3};// trueSystem.out.println(ArrayUtil.contains(f, 3));
判斷對象是否為數組
int[] g = {1,2,3};int h = 1;// trueSystem.out.println(ArrayUtil.isArray(g));// falseSystem.out.println(ArrayUtil.isArray(h));
轉為字符串
int[] i = {1,2,3};// [1, 2, 3]System.out.println(ArrayUtil.toString(i));// 第二個參數為間隔符, 1/2/3System.out.println(ArrayUtil.join(i, '/'));隨機工具
基本使用
RandomUtil.randomInt 獲得指定范圍內的隨機數
RandomUtil.randomBytes 隨機bytes
RandomUtil.randomEle 隨機獲得列表中的元素
RandomUtil.randomEleSet 隨機獲得列表中的一定量的不重復元素,返回Set
RandomUtil.randomString 獲得一個隨機的字符串(只包含數字和字符)
RandomUtil.randomNumbers 獲得一個只包含數字的字符串
RandomUtil.randomUUID 隨機UUID
RandomUtil.weightRandom 權重隨機生成器,傳入帶權重的對象,然后根據權重隨機獲取對象
唯一ID工具UUID
UUID全稱通用唯一識別碼(universally unique identifier)
//生成的UUID是帶-的字符串String uuid = IdUtil.randomUUID();System.out.println(uuid);//生成的是不帶-的字符串String simpleUUID = IdUtil.simpleUUID();System.out.println(simpleUUID);
ObjectId
ObjectId是MongoDB數據庫的一種唯一ID生成策略,是UUID version1的變種。
//生成idString id = ObjectId.next();System.out.println(id);//方法2:從Hutool-4.1.14開始提供String id2 = IdUtil.objectId();System.out.println(id2);
Snowflake
分布式系統中,有一些需要使用全局唯一ID的場景,有些時候我們希望能使用一種簡單一些的ID,并且希望ID能夠按照時間有序生成。Twitter的Snowflake 算法就是這種生成器。
//參數1為終端ID//參數2為數據中心IDSnowflake snowflake = IdUtil.getSnowflake(1, 1);long id3 = snowflake.nextId();System.out.println(id3);壓縮工具
壓縮
打包到當前目錄
//將aaa目錄下的所有文件目錄打包到d:/aaa.zipZipUtil.zip('d:/aaa');
打包到指定目錄
//將aaa目錄下的所有文件目錄打包到d:/bbb/目錄下的aaa.zip文件中// 此處第二個參數必須為文件,不能為目錄ZipUtil.zip('d:/aaa', 'd:/bbb/aaa.zip');//將aaa目錄下的所有文件目錄打包到d:/bbb/目錄下的ccc.zip文件中ZipUtil.zip('d:/aaa', 'd:/bbb/ccc.zip');
多個文件進行打包
ZipUtil.zip(FileUtil.file('d:/bbb/ccc.zip'), false, FileUtil.file('d:/test1/file1.txt'), FileUtil.file('d:/test1/file2.txt'), FileUtil.file('d:/test2/file1.txt'), FileUtil.file('d:/test2/file2.txt'));
解壓
//將test.zip解壓到e:aaa目錄下,返回解壓到的目錄File unzip = ZipUtil.unzip('E:aaatest.zip', 'e:aaa');
身份證工具
主要方法為:
isValidCard 驗證身份證是否合法
convert15To18 身份證15位轉18位
getBirthByIdCard 獲取生日
getAgeByIdCard 獲取年齡
getYearByIdCard 獲取生日年
getMonthByIdCard 獲取生日月
getDayByIdCard 獲取生日天
getGenderByIdCard 獲取性別
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, '內蒙古');
聲明本次數據摘自HuTool官網,為隨即編造,如有雷同,純屬巧合。
集合類集合工具轉為字符串
第二個參數為連接符
String[] col= new String[]{'l','o','l','l','y'};List<String> colList = CollUtil.newArrayList(col);String str = CollUtil.join(colList, '#'); // l#o#l#l#ySystem.out.println(str);
分頁
//Integer比較器Comparator<Integer> comparator = new Comparator<Integer>(){ @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); }};//新建三個列表,CollUtil.newArrayList方法表示新建ArrayList并填充元素List<Integer> list1 = CollUtil.newArrayList(1, 2, 3);List<Integer> list2 = CollUtil.newArrayList(4, 5, 6);List<Integer> list3 = CollUtil.newArrayList(7, 8, 9);//參數表示把list1,list2,list3合并并按照從小到大排序后,取0~2個(包括第0個,不包括第2個),結果是[1,2]@SuppressWarnings('unchecked')List<Integer> result = CollUtil.sortPageAll(0, 2, comparator, list1, list2, list3);System.out.println(result); //輸出 [1,2]
可能接觸時間有點少,沒讀太懂,直接略過了。
創建容器
HashMap<String, String> map = CollUtil.newHashMap();HashSet<String> set = CollUtil.newHashSet();ArrayList<String> list = CollUtil.newArrayList();
添加元素
CollUtil.setOrAppend(list, 0, '1');System.out.println(list);
調整數據大小
List<String> list5 = CollUtil.reverse(list);
沒有搞懂改變List大小有啥用。。。,希望有會的指點一下
合并數組
List<String> list4 = new ArrayList<>();List<String> list6 = new ArrayList<>();list4.add('lolly');list6.add('lolly1023'); CollUtil.addAll(list4, list6); // [lolly, lolly1023]System.out.println(list4);
截取數組
// [lolly]System.out.println(CollUtil.sub(list4, 0, 1));
判斷是否為空
// falseSystem.out.println(CollUtil.isEmpty(list4));// trueSystem.out.println(CollUtil.isNotEmpty(list4));
集合生成Map
源自python語法糖
Collection<String> keys = CollUtil.newArrayList('a', 'b', 'c', 'd');Collection<Integer> values = CollUtil.newArrayList(1, 2, 3, 4);// {a=1,b=2,c=3,d=4}Map<String, Integer> map = CollUtil.zip(keys, values);
過濾方法
此方法可以過濾掉map中不需要的key舉例:
@Testpublic void CollUtil_Filter() { Map<String, Object> m = new HashMap<String, Object>() {{ put('k1', 'v1'); put('k2', 'v2'); put('k3', 'v3'); }}; String[] inc = {'k1', 'k3'};//需要的key List<String> incList = Arrays.asList(inc); m = CollectionUtil.filter(m, new Editor<Map.Entry<String, Object>>() { @Override public Map.Entry<String, Object> edit(Map.Entry<String, Object> stringObjectEntry) { if (incList.contains(stringObjectEntry.getKey())) { return stringObjectEntry; } return null; } }); log.info('{}', m);}
控制臺輸出
{k3=v3, k1=v1}
列表工具過濾列表
對每一個元素進行過濾
List<String> a = ListUtil.toLinkedList('1', '2', '3');// 結果: [edit1, edit2, edit3]List<String> filter = ListUtil.filter(a, str -> 'edit' + str);
獲取滿足規則元素下標
List<String> a = ListUtil.toLinkedList('1', '2', '3', '4', '3', '2', '1');// [1, 5]int[] indexArray = ListUtil.indexOfAll(a, '2'::equals);
Iterator工具
基本方法
isEmpty 是否為null或者無元素
isNotEmpty 是否為非null或者至少一個元素
hasNull 是否有null元素
isAllNull 是否全部為null元素
countMap 根據集合返回一個元素計數的Map,所謂元素計數就是假如這個集合中某個元素出現了n次,那將這個元素做為key,n做為value
join 使用分隔符將集合轉換為字符串
toMap toMap Entry列表轉Map,或者key和value單獨列表轉Map
asIterator Enumeration轉Iterator
asIterable Iterator轉Iterable
getFirst 獲取列表的第一個元素
getElementType 獲取元素類型
Map
Map工具
行轉列
如若map中的數據為:
[ {a: 1, b: 1, c: 1}, {a: 2, b: 2}, {a: 3, b: 3}, {a: 4}]
則使用toListMap之后變為:
{ a: [1,2,3,4], b: [1,2,3,], c: [1]}
列轉行
如若map中的數據為:
{ a: [1,2,3,4], b: [1,2,3,], c: [1]}
則使用toMapList之后變為:
[ {a: 1, b: 1, c: 1}, {a: 2, b: 2}, {a: 3, b: 3}, {a: 4}]
轉為字符串
join、joinIgnoreNull、sortJoin將Map按照給定的分隔符轉換為字符串,此方法一般用于簽名。
Map<String, String> build = MapUtil.builder(new HashMap<String, String>()) .put('key1', 'value1') .put('key3', 'value3') .put('key2', 'value2').build();// key1value1key2value2key3value3String join1 = MapUtil.sortJoin(build, StrUtil.EMPTY, StrUtil.EMPTY, false);// key1value1key2value2key3value3123String join2 = MapUtil.sortJoin(build, StrUtil.EMPTY, StrUtil.EMPTY, false, '123');
過濾方法
舉例:
Map<String, String> map = MapUtil.newHashMap();map.put('a', '1');map.put('b', '2');map.put('c', '3');map.put('d', '4');Map<String, String> map2 = MapUtil.filter(map, (Filter<Entry<String, String>>) t -> Convert.toIn(t.getValue()) % 2 == 0);
結果為:
{ b: '2', d: '4'}
key和value互換
舉例:
Map<String, String> map = MapUtil.newHashMap(); map.put('a', '1'); map.put('b', '2'); map.put('c', '3'); map.put('d', '4');Map<String, String> map2 = MapUtil.reverse(map);
結果為:
{ '1': 'a', '2': 'b', '3': 'c', '4': 'd',}
BiMap
BiMap,它實現了一種雙向查找的功能,即根據key查找value和根據value查找key,Hutool也同樣提供此對象。
基本使用
BiMap<String, Integer> biMap = new BiMap<>(new HashMap<>());biMap.put('aaa', 111);biMap.put('bbb', 222);// 111biMap.get('aaa');// 222biMap.get('bbb');// aaabiMap.getKey(111);// bbbbiMap.getKey(222);
TableMap
TableMap這類數據結構,通過鍵值單獨建立List方式,使鍵值對一一對應,實現正向和反向兩種查找。
基本使用
TableMap<String, Integer> tableMap = new TableMap<>(new HashMap<>());tableMap.put('aaa', 111);tableMap.put('bbb', 222);// 111tableMap.get('aaa');// 222tableMap.get('bbb');// aaatableMap.getKey(111);// bbbtableMap.getKey(222);// [111]tableMap.getValues('aaa');//[aaa]tableMap.getKeys(111);
Codec編碼
Base62編碼解碼
String a = 'Base62';// KixpUr22String encode = Base62.encode(a);System.out.println(encode);// 還原為Base62String decodeStr = Base62.decodeStr(encode);System.out.println(decodeStr);
Base64編碼解碼
String a = 'Base64';// QmFzZTY0String encode = Base64.encode(a);System.out.println(encode);// 還原為Base64String decodeStr = Base64.decodeStr(encode);System.out.println(decodeStr);
Base32編碼解碼
String a = 'Base32';// IJQXGZJTGIString encode = Base32.encode(a);System.out.println(encode);// 還原為Base32String decodeStr = Base32.decodeStr(encode);System.out.println(decodeStr);
文本操作 StrBuilder
在JDK提供的StringBuilder中,拼接字符串變得更加高效和靈活,但是生成新的字符串需要重新構建StringBuilder對象,造成性能損耗和內存浪費,因此Hutool提供了可復用的StrBuilder。
摘自HuTool官網
基本使用
StrBuilder builder = StrBuilder.create();builder.append('lolly').append('1023').append(’!’);// lolly1023!System.out.println(builder);
對比StringBuilder來說,性能幾乎提升一倍之高。
Unicode編碼轉換工具
字符串轉Unicode符
//第二個參數true表示跳過ASCII字符(只跳過可見字符)String s = UnicodeUtil.toUnicode('lolly1023中文', true);// lolly1023u4e2du6587System.out.println(s);
Unicode轉字符串
String str = 'lolly1023u4e2du6587';String res = UnicodeUtil.toString(str);// lolly1023中文System.out.println(res);
比較器
版本比較器
// 1.2.1 < 1.12.1,返回-1System.out.println(VersionComparator.INSTANCE.compare('1.2.1', '1.12.1'));// 1.12.1 < 1.12.1c,返回-1System.out.println(VersionComparator.INSTANCE.compare('1.12.1', '1.12.1c'));// V0.0.20170102 > V0.0.20170101,返回1System.out.println(VersionComparator.INSTANCE.compare('V0.0.20170102', 'V0.0.20170101'));
其它比較器
ReverseComparator 反轉比較器,排序時提供反序
VersionComparator 版本比較器,支持如:1.3.20.8,6.82.20160101,8.5a/8.5c等版本形式
PropertyComparator Bean屬性比較器,通過Bean的某個屬性來對Bean對象進行排序
IndexedComparator 按照數組的順序正序排列,數組的元素位置決定了對象的排序先后
ComparatorChain 比較器鏈。此鏈包裝了多個比較器,最終比較結果按照比較器順序綜合多個比較器結果。PinyinComparator 按照GBK拼音順序對給定的漢字字符串排序。
異常
基本方法
getMessage 獲得完整消息,包括異常名
wrap 包裝一個異常為指定類型異常
wrapRuntime 使用運行時異常包裝編譯異常
getCausedBy 獲取由指定異常類引起的異常
isCausedBy 判斷是否由指定異常類引起
stacktraceToString 堆棧轉為完整字符串
其他方法請參考API文檔:API文檔
其它異常封裝
DependencyException 依賴異常
StatefulException 帶有狀態碼的異常
UtilException 工具類異常
NotInitedException 未初始化異常
ValidateException 驗證異常
圖片
圖片工具
縮放圖片
ImgUtil.scale(FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美縮小版.jpg'),0.5f// 縮放比例);
剪裁圖片
ImgUtil.cut( FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美剪裁版.jpg'), new Rectangle(200, 200, 200, 200)//裁剪的矩形區域);
分成行列剪裁
ImgUtil.slice(FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美'),2, 2);
圖片類型轉換
ImgUtil.convert(FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美.png'));
圖片轉為黑白
ImgUtil.gray(FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美黑白版.jpg'));
添加文字水印
ImgUtil.pressText(// FileUtil.file('d:/桌面/石原里美.jpg'), // FileUtil.file('d:/桌面/石原里美水印版.jpg'), // 'lolly1023', Color.WHITE, //文字 new Font('黑體', Font.BOLD, 100), //字體 0, //x坐標修正值。 默認在中間,偏移量相對于中間偏移 0, //y坐標修正值。 默認在中間,偏移量相對于中間偏移 0.8f//透明度:alpha 必須是范圍 [0.0, 1.0] 之內(包含邊界值)的一個浮點數字);
添加圖片水印
ImgUtil.pressImage( FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美圖片水印版.jpg'), ImgUtil.read(FileUtil.file('d:/桌面/石原里美.jpg')), //水印圖片 0, //x坐標修正值。 默認在中間,偏移量相對于中間偏移 0, //y坐標修正值。 默認在中間,偏移量相對于中間偏移 0.1f);
旋轉圖片
// 旋轉180度BufferedImage image = (BufferedImage) ImgUtil.rotate(ImageIO.read(FileUtil.file('d:/桌面/石原里美.jpg')), 180);ImgUtil.write(image, FileUtil.file('d:/桌面/石原里美旋轉版.jpg'));
水平翻轉圖片
ImgUtil.flip(FileUtil.file('d:/桌面/石原里美.jpg'), FileUtil.file('d:/桌面/石原里美翻轉版.jpg'));
圖片編輯器
圖像切割
Img.from(FileUtil.file('d:/桌面/石原里美.jpg')) .cut(0, 0, 200)// .write(FileUtil.file('d:/桌面/石原里美切割版.jpg') );
圖片壓縮
圖片壓縮只支持jpg文件
Img.from(FileUtil.file('d:/桌面/石原里美.jpg')) .setQuality(0.5)//壓縮比率 .write(FileUtil.file('d:/桌面/石原里美壓縮版.jpg') );
HuTool暫未學完,持續更新
本文的所有代碼均已上傳GitHub,HuTool學習
到此這篇關于Java開發常用類庫之Hutool的文章就介紹到這了,更多相關Java Hutool類庫內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章: