不要重複造輪子?提高生產效率!5個超好用的開源工具庫分享
來源:JavaGuide
在實際專案開發中,從穩定性和效率的角度考慮,重複造輪子是不被提倡的。但是,自己在學習過程中造輪子絕對是對自己百利而無一害的,造輪子是一種特別能夠提高自己系統程式設計能力的手段。
今天分享幾個我常用的開源工具庫:
MyExcel: 功能全面的 Excel 處理工具,記憶體佔用低,效能也很優秀。 OSHI:一款為 Java 語言提供的基於 JNA 的(本機)作業系統和硬體資訊庫。 JsonPath:讀取 JSON 的 Java DSL Caffeine:強大的本地快取 Hutool:超全的 Java 工具庫
以下是較為詳細一點的介紹,建議小夥伴們看完,方便自己快速上手,用在自己的專案中來提高生產效率。
MyExcel:Excel 處理
專案介紹
EasyExcel 大家應該都不陌生,這是阿里開源的一款 Excel 處理工具,可以避免大檔案記憶體溢位問題,我之前也推薦過幾次這個專案。
MyExcel 也是一個 Excel 處理工具,同樣可以避免大檔案記憶體溢位問題,並且功能更全面,記憶體佔用更低,效能也更優秀(根據官方測試對比結果得出)。
根據專案 wiki 中的測試資料:
24.3M Excel,50 萬行,8 列,迴圈 40 次讀取,記憶體平均佔用約 75 兆左右,與阿里 EasyExcel(V2.1.6)同檔案測試對比,記憶體佔用約為 MyExcel 的三分之一
MyExcel 的核心優勢如下:
依賴資訊
Maven 倉庫地址: 。
Maven :
<dependency>
<groupId>com.github.liaochong</groupId>
<artifactId>myexcel</artifactId>
<version>4.3.0.RC4</version>
</dependency>
Gradle :
implementation 'com.github.liaochong:myexcel:4.3.0.RC4'
功能演示
MyExcel 的功能比較多,這裡只挑選個別介紹,詳細介紹可以檢視官方 wiki: 。
1、流式匯出
MyExcel 支援流式匯出,採用生產者消費者模式,允許分批獲取資料,記憶體佔用極低。另外,流式匯出支援 zip 壓縮包等獨有特性。
DefaultStreamExcelBuilder<ArtCrowd> streamExcelBuilder = DefaultStreamExcelBuilder
.of(ArtCrowd.class) // 如匯出Map型別資料,請使用of(Map.class)
.threadPool(Executors.newFixedThreadPool(10))// 執行緒池,可選
.templateHandler(FreemarkerTemplateHandler.class)// 追加模板資料,可選,適合極度個性化資料匯出
.capacity(10_000)// 容量設定,在主動劃分excel使用,可選
.start();
2、自定義樣式
MyExcel 支援自定義樣式,包含寬度、高度、背景色、邊框、字型等樣式的調整,具體介紹請參考:/Style-support 。
標題(title)樣式自定義:
ExcelColumn(style={"title->color:red","cell->color:green"})
Integer age;
內容行樣式自定義:
@ExcelColumn(style="cell->color:green")
Integer age;
方法呼叫設定樣式:
DefaultExcelBuilder.of(ArtCrowd.class)
.style("title->color:red","background-color:green;")
.build(dataList);
3、下拉選單
MyExcel 支援生成下拉選單,只需要傳入 List 或者 Array 引數即可。
@ExcelColumn(title="下拉選單")
List<String> options;
相關地址
專案地址: 官方文件:
OSHI:本機資訊獲取
專案介紹
OSHI 是一款為 Java 語言提供的基於 JNA 的(本機)作業系統和硬體資訊庫。
[JNA(Java Native Access)]( "JNA(Java Native Access "JNA(Java Native Access)")")是一個開源的 Java 框架,是 Sun 公司推出的一種呼叫本地方法的技術,是建立在經典的 JNI 基礎之上的一個框架。之所以說它是 JNI 的替代者,是因為 JNA 大大簡化了呼叫本地方法的過程,使用很方便,基本上不需要脫離 Java 環境就可以完成。
JNI (Java Native Interface)即 Java 本地介面,它建立了 Java 與其他程式語言的橋樑,允許 Java 程式呼叫其他語言(尤其是 C/C++ )編寫的程式或者程式碼庫。並且, JDK 本身的實現也大量用到 JNI 技術來呼叫本地 C 程式庫。
透過 OSHI ,我們不需要安裝任何其他本機庫,就能檢視記憶體和 CPU 使用率、磁碟和分割槽使用情況、裝置、感測器等資訊。
OSHI 旨在提供一種跨平臺的實現來檢索系統資訊,支援 Windows、Linux、MacOS、Unix 等主流作業系統。
官方是這樣介紹 oshi 的:(翻譯 Chrome 外掛:Mate Translate):
使用 oshi 你可以輕鬆製作出專案常用的系統監控功能,如下圖所示:
依賴資訊
Maven 倉庫地址: 。
Maven:
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-parent</artifactId>
<version>6.4.1</version>
<type>pom</type>
</dependency>
Gradle:
implementation 'com.github.oshi:oshi-core:6.4.1'
功能演示
獲取硬體資訊物件HardwareAbstractionLayer
:
//系統資訊
SystemInfo si = new SystemInfo();
//作業系統資訊
OperatingSystem os = si.getOperatingSystem();
//硬體資訊
HardwareAbstractionLayer hal = si.getHardware();
// 磁碟資訊
List<HWDiskStore> diskStores = hal.getDiskStores();
有了代表硬體資訊的物件HardwareAbstractionLayer
之後,我們就可以獲取硬體相關的資訊了!
下面簡單演示一下獲取記憶體和 CPU 相關資訊。
1、獲取記憶體相關資訊
//記憶體相關資訊
GlobalMemory memory = hal.getMemory();
//獲取記憶體總容量
String totalMemory = FormatUtil.formatBytes(memory.getTotal());
//獲取可用記憶體的容量
String availableMemory = FormatUtil.formatBytes(memory.getAvailable());
有了記憶體總容量和記憶體可用容量,你就可以計算出當前記憶體的利用率了。
2、獲取 CPU 相關資訊
//CPU相關資訊
CentralProcessor processor = hal.getProcessor();
//獲取CPU名字
String processorName = processor.getProcessorIdentifier().getName();
//獲取物理CPU數
int physicalPackageCount = processor.getPhysicalPackageCount();
//獲取物理核心數
int physicalProcessorCount = processor.getPhysicalProcessorCount();
相關地址
專案地址: 官網:
JsonPath:讀取 JSON 的 Java DSL
專案介紹
JsonPath 一種面向 JSON 結構的查詢語言。相當於 XPATH 對於 XML、SQL 對於關係型資料庫,它們都是比較通用的 DSL 。
JsonPath 提供了多種語言的實現版本,包括:Java、Javascript、Python、PHP、Ruby、Go 等。我們這裡以 Java 版本的實現為例。
依賴資訊
Maven 倉庫地址: 。
Maven:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.8.0</version>
</dependency>
Gradle:
implementation 'com.jayway.jsonpath:json-path:2.8.0'
功能演示
測試 json 文件內容如下:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
讀取所有書籍的作者:
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
讀取所有書籍並過濾:
// 所有價格低於 10 的書籍
List<Map<String, Object>> books = JsonPath.parse(json)
.read("$.store.book[?(@.price < 10)]");
// 也可以透過 Filter API 來進行過濾
Filter cheapFictionFilter = filter(
where("category").is("fiction").and("price").lte(10D)
);
List<Map<String, Object>> books = JsonPath.parse(json).read("$.store.book[?]", cheapFictionFilter);
相關地址
專案地址: JSONPath 介紹:
Caffeine:強大的本地快取
專案介紹
Caffeine 是我最常用的一款本地快取,類似於 ConcurrentMap
,但提供快取功能更全面,效能也非常強悍。
效能有多牛呢?官方文件的基準測試中已經給出了詳細的答案,地址: 。
下圖是 8 執行緒 對一個配置了最大容量的快取進行併發讀和寫,常見的本地快取實現方案的效能對比。
併發讀:
併發寫:
除了基本的快取功能之外,Caffeine 還提供了過期、非同步載入等功能。
Caffeine 算的上是本地快取的最佳選擇,像 Redisson、Cassandra、Hbase、Neo4j、Druid 等知名開源專案都用到了 Caffeine。
依賴資訊
Maven 倉庫地址: 。
Java 11 及以上版本使用 3.x
,否則使用2.x
。
Maven:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.5</version>
</dependency>
Gradle:
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.5'
功能演示
Caffeine 和 API 和 Guava 很像,借鑑了 Guava 的設計。
建立快取:
Cache<Key, Graph> cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000)
.build();
手動移除快取:
// 單個key
cache.invalidate(key)
// 批次key
cache.invalidateAll(keys)
// 所有key
cache.invalidateAll()
統計:
// 統計快取命中率、快取回收數量、載入新值的平均時間
Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.recordStats()
.build();
相關地址
專案地址: 官方文件:/wiki
Hutool:超全的 Java 工具庫
專案介紹
Hutool 是一個非常使用的 Java 工具類庫,對檔案、流、加密解密、轉碼、正則、執行緒、XML 等 JDK 方法進行了封裝。
真心是一個不錯的工具庫,功能全面,非常適合在自己的專案中使用。
官方是這樣介紹 Hutool 的:
依賴資訊
Maven 倉庫地址: 。
Maven:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
Gradle:
implementation 'cn.hutool:hutool-all:5.8.16'
功能演示
簡單演示幾個個人覺得比較實用的功能。
型別轉換
Convert
類封裝了針對 Java 常見型別的轉換。
long[] b = {1,2,3,4,5};
String bStr = Convert.toStr(b);//"[1, 2, 3, 4, 5]"
double a = 67556.32;
String digitUppercase = Convert.digitToChinese(a);//"陸萬柒仟伍佰伍拾陸元叄角貳分"
郵件
在 Java 中傳送郵件主要品依靠 javax.mail
包,但是由於使用比較繁瑣,因此 Hutool 針對其做了封裝。
在 classpath(在標準 Maven 專案中為src/main/resources
)的 config 目錄下新建mail.setting
檔案,完整配置如下(郵件伺服器必須支援並開啟 SMTP 協議):
# 郵件伺服器的SMTP地址,可選,預設為smtp.<發件人郵箱字尾>
host = smtp.yeah.net
# 郵件伺服器的SMTP埠,可選,預設25
port = 25
# 發件人(必須正確,否則傳送失敗)
from = hutool@yeah.net
# 使用者名稱,預設為發件人郵箱字首
user = hutool
# 密碼(注意,某些郵箱需要為SMTP服務單獨設定授權碼,詳情檢視相關幫助)
pass = q1w2e3
傳送郵件非常簡單:
MailUtil.send("hutool@foxmail.com", "測試", "郵件來自Hutool測試", false);
支援群發:
ArrayList<String> tos = CollUtil.newArrayList(
"person1@bbb.com",
"person2@bbb.com",
"person3@bbb.com",
"person4@bbb.com");
MailUtil.send(tos, "測試", "郵件來自Hutool群發測試", false);
支援新增一個或者多個附件:
MailUtil.send("hutool@foxmail.com", "測試", "<h1>郵件來自Hutool測試</h1>", true, FileUtil.file("d:/aaa.xml"));
除了使用配置檔案定義全域性賬號以外,MailUtil.send
方法同時提供過載方法可以傳入一個MailAccount
物件,這個物件為一個普通 Bean,記錄了郵件伺服器資訊。
MailAccount account = new MailAccount();
account.setHost("smtp.yeah.net");
account.setPort("25");
account.setAuth(true);
account.setFrom("hutool@yeah.net");
account.setUser("hutool");
account.setPass("q1w2e3");
MailUtil.send(account, CollUtil.newArrayList("hutool@foxmail.com"), "測試", "郵件來自Hutool測試", false);
唯一 ID
在分散式環境中,唯一 ID 生成應用十分廣泛,生成方法也多種多樣,Hutool 針對一些常用生成策略做了簡單封裝。
Hutool 提供的唯一 ID 生成器的工具類,涵蓋了:
UUID ObjectId(MongoDB) Snowflake(Twitter)
拿 UUID 舉例!
Hutool 重寫java.util.UUID
的邏輯,對應類為cn.hutool.core.lang.UUID
,使生成不帶-的 UUID 字串不再需要做字元替換,效能提升一倍左右。
//生成的UUID是帶-的字串,類似於:a5c8a5e8-df2b-4706-bea4-08d0939410e3
String uuid = IdUtil.randomUUID();
//生成的是不帶-的字串,類似於:b17f24ff026d40949c85a24f4f375d42
String simpleUUID = IdUtil.simpleUUID();
HTTP 請求工具類
針對最為常用的 GET 和 POST 請求,HttpUtil 封裝了兩個方法,
HttpUtil.get
HttpUtil.post
GET 請求:
// 最簡單的HTTP請求,可以自動透過header等資訊判斷編碼,不區分HTTP和HTTPS
String result1= HttpUtil.get(");
// 當無法識別頁面編碼的時候,可以自定義請求頁面的編碼
String result2= HttpUtil.get(", CharsetUtil.CHARSET_UTF_8);
//可以單獨傳入http引數,這樣引數會自動做URL編碼,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result3= HttpUtil.get(", paramMap);
POST 請求:
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result= HttpUtil.post(", paramMap);
檔案上傳:
HashMap<String, Object> paramMap = new HashMap<>();
//檔案上傳只需將引數中的鍵指定(預設file),值設為檔案物件即可,對於使用者來說,檔案上傳與普通表單提交併無區別
paramMap.put("file", FileUtil.file("D:\\face.jpg"));
String result= HttpUtil.post(", paramMap);
快取
Hutool 提供了常見的幾種快取策略的實現:
FIFO(first in first out) :先進先出策略。 LFU(least frequently used) :最少使用率策略。 LRU(least recently used) :最近最久未使用策略。 Timed :定時策略。 Weak :弱引用策略。
並且,Hutool 還支援將小檔案以 byte[]
的形式快取到內容中,減少檔案的訪問,以解決頻繁讀取檔案引起的效能問題。
FIFO(first in first out) 策略快取使用:
Cache<String,String> fifoCache = CacheUtil.newFIFOCache(3);
//加入元素,每個元素可以設定其過期時長,DateUnit.SECOND.getMillis()代表每秒對應的毫秒數,在此為3秒
fifoCache.put("key1", "value1", DateUnit.SECOND.getMillis() * 3);
fifoCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 3);
fifoCache.put("key3", "value3", DateUnit.SECOND.getMillis() * 3);
//由於快取容量只有3,當加入第四個元素的時候,根據FIFO規則,最先放入的物件將被移除
fifoCache.put("key4", "value4", DateUnit.SECOND.getMillis() * 3);
//value1為null
String value1 = fifoCache.get("key1");
控制檯列印封裝
一般情況下,我們列印資訊到控制檯小夥伴們應該再熟悉不過了!
System.out.println("Hello World");
但是,這種方式不滿足很多場景的需要:
不支援引數,物件列印需要拼接字串 不能直接列印陣列,需要手動呼叫 Arrays.toString
為此,Hutool 封裝了Console
物件。
Console
物件的使用更加類似於 Javascript 的console.log()
方法,這也是借鑑了 JS 的一個語法糖。
String[] a = {"java", "c++", "c"};
Console.log(a);//控制檯輸出:[java, c++, c]
Console.log("This is Console log for {}.", "test");//控制檯輸出:This is Console log for test.
加密解密
Hutool 支援對稱加密、非對稱加密、摘要加密、訊息認證碼演算法、國密。
這裡以國密為例,Hutool 針對Bouncy Castle
做了簡化包裝,用於實現國密演算法中的 SM2、SM3、SM4。
國密演算法需要引入Bouncy Castle
庫的依賴:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
SM2 使用自定義金鑰對加密或解密 :
String text = "JavaGuide:一份涵蓋大部分 Java 程式設計師所需要掌握的核心知識。準備 Java 面試,首選 JavaGuide!";
System.out.println("原文:" + text);
KeyPair pair = SecureUtil.generateKeyPair("SM2");
// 公鑰
byte[] privateKey = pair.getPrivate().getEncoded();
// 私鑰
byte[] publicKey = pair.getPublic().getEncoded();
SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
// 公鑰加密,私鑰解密
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
System.out.println("加密後:" + encryptStr);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
System.out.println("解密後:" + decryptStr);
SM2 簽名和驗籤 :
//加簽
String sign = sm2.signHex(HexUtil.encodeHexStr(text));
System.out.println("簽名:" + sign);
//驗籤
boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(text), sign);
System.out.println("驗籤:" + verify);
執行緒池
Hutool 支援使用建造者的模式建立自定義執行緒池,這樣看著更加清晰。
private static ExecutorService pool = ExecutorBuilder.create()
.setCorePoolSize(10)//初始池大小
.setMaxPoolSize(20) //最大池大小
.setWorkQueue(new LinkedBlockingQueue<>(100))//最大等待數為100
.setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix("IM-Pool-").build())// 執行緒池命名
.build();
實際專案中,如果一個物件的屬性比較多,有限考慮使用建造者模式建立物件。
並且,Hutool 還提供一個全域性的執行緒池,預設所有非同步方法在這個執行緒池中執行。
ThreadUtil.execute
: 直接在公共執行緒池中執行執行緒ThreadUtil.execAsync
: 執行非同步方法......
Hutool 自身就大量用到了 ThreadUtil
,比如敏感詞工具類 SensitiveUtil
:
public static void init(final Collection<String> sensitiveWords, boolean isAsync){
if(isAsync){
// 非同步初始化敏感詞樹
ThreadUtil.execAsync(new Callable<Boolean>(){
@Override
public Boolean call() throws Exception {
init(sensitiveWords);
return true;
}
});
}else{
// 同步初始化敏感詞樹
init(sensitiveWords);
}
}
相關地址
專案地址: 官網:
後記
Java 的一大優勢就是生態特別好, 包含了許多好用的工具類庫和框架,幾乎覆蓋了所有的需求場景。很多事情我們完全不需要自己從頭開始做,利用現有的穩定可靠的工具類庫可以大大提高開發效率。
比如 Excel 文件處理,你可以考慮下面這幾個開源的工具類庫:
easyexcel[1] :快速、簡單避免 OOM 的 Java 處理 Excel 工具。 excel-streaming-reader[2]:Excel 流式程式碼風格讀取工具(只支援讀取 XLSX 檔案),基於 Apache POI 封裝,同時保留標準 POI API 的語法。 myexcel[3]:一個集匯入、匯出、加密 Excel 等多項功能的工具包。
再比如 PDF 文件處理:
pdfbox[4] :用於處理 PDF 文件的開放原始碼 Java 工具。該專案允許建立新的 PDF 文件、對現有文件進行操作以及從文件中提取內容。PDFBox 還包括幾個命令列實用程式。PDFBox 是在 Apache 2.0 版許可下發布的。 OpenPDF[5]:OpenPDF 是一個免費的 Java 庫,用於使用 LGPL 和 MPL 開源許可建立和編輯 PDF 檔案。OpenPDF 基於 iText 的一個分支。 itext7[6]:iText 7 代表了想要利用利用好 PDF 的開發人員的更高階別的 sdk。iText 7 配備了更好的文件引擎、高階和低階程式設計功能以及建立、編輯和增強 PDF 文件的能力,幾乎對每個工作流都有好處。 FOP[7] :Apache FOP 專案的主要的輸出目標是 PDF。
我的網站上總結了 Java 開發常用的一些工具類庫,可以作為參考: 。
參考資料
easyexcel:
[2]excel-streaming-reader:
[3]myexcel:
[4]pdfbox:
[5]OpenPDF:
[6]itext7:
[7]FOP:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2952594/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前端常用外掛、工具類庫彙總,不要重複造輪子啦!!!前端
- Go~避免重複造輪子Go
- 別再重複造輪子了,幾個值得應用到專案中的 Java 開源庫送給你Java
- 重複造輪子了, 自己開發的 Laravel RepositoryLaravel
- ?揭祕vue/react元件庫中?5個"作者不造的輪子"VueReact元件
- 談談程式設計師重複造輪子的幾點思考程式設計師
- 答應我,用了這個jupyter外掛,別再重複造輪子了
- 造一個「輪子」musionUIUI
- flutter好用的輪子推薦六-超好用的全域性toastFlutterAST
- flutter好用的輪子推薦三-超強輪播圖SwiperFlutter
- 提高生產力的 Flutter 開發工具 - bisunajaimeFlutterAI
- iOS 好用的輪子iOS
- 給 Java 造個輪子 - ChainJavaAI
- 造了個滾輪控制元件輪子控制元件
- 又雙叒叕造新輪子:重構了自己寫的mvvm庫MVVM
- 常用的幾個提高iOS開發效率的開源類庫及工具iOS
- 推薦幾個開源類庫,超好用,遠離996!996
- ERP系統是如何提高生產效率的?
- 東莞mes系統:提高生產效率的利器
- 提升網際網路產品開發效率的5個工具組合
- 【譯】提高React開發效率的5個工具React
- 提高 Linux 開發效率的 5 個工具Linux
- 提高生產力!這10個Lambda表示式必須掌握,開發效率嘎嘎上升!
- 「造個輪子」——cicada 原始碼分析原始碼
- 好久不見,我造了一個輪子:微開發
- 造輪子-ThreadPoolExecutorthread
- 【小程式】實現複用及造輪子入門
- 【推薦】7個超好用的Python開發工具!Python
- 開源 5 款超好用的資料庫 GUI 帶你玩轉 MongoDB、Redis、SQL 資料庫資料庫GUIMongoDBRedisSQL
- 分享一個能讓你的研發效率提升超過20%的工具
- 力薦 35 個最好用的 Vue 開源庫!Vue
- 超好用的5款開發工具,Python初習者必看Python
- 簡化 Go 開發:使用強大的工具提高生產力Go
- 重複造輪子系列——基於Ocelot實現類似支付寶介面模式的閘道器模式
- 分享一個JDK批量非同步任務工具CompletionService,超好用JDK非同步
- 最新Android開源庫、工具、開源專案整理分享Android
- 【安利】超好用的第三方登入的開源庫
- 又造了一個輪子—session庫!使用簡單!支援多儲存!Session