別再重復(fù)造輪子了,推薦使用 Google Guava 開(kāi)源工具類(lèi)庫(kù),真心強(qiáng)大!
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)

2、guava github 開(kāi)源地址:GitHub - google/guava:
??com.google.guava
??guava
??29.0-jre
不可變集合與對(duì)象
1、制作對(duì)象的不可變副本是一種很好的防御性編程技術(shù),不可變對(duì)象有許多優(yōu)點(diǎn),包括:
可供不受信任的庫(kù)安全使用。 線(xiàn)程安全:可由多個(gè)線(xiàn)程使用,無(wú)爭(zhēng)用風(fēng)險(xiǎn)。 不需要支持突變,并且可以節(jié)省時(shí)間和空間,所有不可變的集合實(shí)現(xiàn)都比它們的可變同級(jí)更節(jié)省內(nèi)存。 可以用作常數(shù),并期望它將保持不變。 最新面試題大家可以在Java面試庫(kù)小程序在線(xiàn)刷題。
2、要點(diǎn):每個(gè) Guava 不可變集合實(shí)現(xiàn)都拒絕 null 值。Guava 的設(shè)計(jì)上推薦使用 null 值,大多數(shù)情況下,遇到 null 值會(huì)拋異常.
3、一個(gè)不可變的 ImmutableXxx 集合可以通過(guò)以下幾種方式創(chuàng)建:
使用 copyOf 方法,如 ImmutableSet.copyOf(set)使用 of 方法, 如 ImmutableSet.of("a", "b", "c")或ImmutableMap.of("a", 1, "b", 2)使用 Builder 方法,。
4、Guava 為 java jdk 每種標(biāo)準(zhǔn)集合類(lèi)型提供了簡(jiǎn)單易用的不可變版本,包括 Guava 自己的集合變體,為 java 提供的不可變版本都是繼承 java jdk 的接口而來(lái),所以操作上基本無(wú)異。下面接口的實(shí)現(xiàn)類(lèi)也都有對(duì)應(yīng)的不可變版本。
| 接口 | JDK 或者 Guava | 不可變版本 |
|---|---|---|
| Collection | JDK | ImmutableCollection |
| List | JDK | ImmutableList |
| Set | JDK | ImmutableSet |
| SortedSet/NavigableSet | JDK | ImmutableSortedSet |
| Map | JDK | ImmutableMap |
| SortedMap | JDK | ImmutableSortedMap |
| Multiset | Guava | ImmutableMultiset |
| SortedMultiset | Guava | ImmutableSortedMultiset |
| Multimap | Guava | ImmutableMultimap |
| ListMultimap | Guava | ImmutableListMultimap |
| SetMultimap | Guava | ImmutableSetMultimap |
| BiMap | Guava | ImmutableBiMap |
| ClassToInstanceMap | Guava | ImmutableClassToInstanceMap |
| Table | Guava | ImmutableTable |
在線(xiàn)演示源碼:
https://github.com/main/java/com/wmx/guava/ImmutableCollectionTest.java
官網(wǎng)文檔
https://github.com/google/guava/wiki/ImmutableCollectionsExplained
推薦一個(gè) Spring Boot 基礎(chǔ)教程及實(shí)戰(zhàn)示例:
https://github.com/javastacks/spring-boot-best-practice
Guava 新集合類(lèi)型
1、Guava 引入了許多新的集合類(lèi)型,這些類(lèi)型不在 Java JDK 中,但卻非常有用,這些都是為了與 JDK 集合框架愉快地共存而設(shè)計(jì)的,而不是將東西塞進(jìn) JDK 集合抽象中。
Multiset 可重復(fù)集合
1、Guava 提供了一個(gè)新的集合類(lèi)型 Multiset,它支持添加多個(gè)相同的元素,其中成員可以出現(xiàn)不止一次。
2、Multiset 相當(dāng)于 Set,區(qū)別在于 Multiset 可添加相同的元素,它的內(nèi)部使用一個(gè) HashMap 來(lái)維護(hù),
3、Multiset 也有自己的實(shí)現(xiàn)類(lèi),常用的有 HashMultiset、LinkedHashMultiset、TreeMultiset 等,HashMultiset 、TreeMultiset 是無(wú)序的,LinkedHashMultiset 是有序的,操作完全同理 JDK 的 HashSet、TreeSet、LinkedHashSet。
在線(xiàn)演示源碼
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/MultisetTest.java
Multimap 多重映射
1、每個(gè)有經(jīng)驗(yàn)的 Java 程序員都曾在某個(gè)地方實(shí)現(xiàn)過(guò) Map或 Map,Guava 的 Multimap 框架使處理從鍵到多個(gè)值的映射變得容易,多重映射是將鍵與任意多個(gè)值關(guān)聯(lián)的一種通用方法。
2、從概念上講,有兩種方法可以將多重映射視為從單個(gè)鍵到單個(gè)值的映射的集合:

3、Multimap 提供了多種實(shí)現(xiàn):
| Multimap | 實(shí)現(xiàn) key 使用的是 | value 使用的是 |
|---|---|---|
| ArrayListMultimap | HashMap | ArrayList |
| HashMultimap | HashMap | HashSet |
| LinkedListMultimap * | LinkedHashMap* | LinkedList* |
| LinkedHashMultimap** | LinkedHashMap | LinkedHashSet |
| TreeMultimap | TreeMap | TreeSet |
| ImmutableListMultimap | ImmutableMap | ImmutableList |
| ImmutableSetMultimap | ImmutableMap | ImmutableSet |
4、除了不可變的實(shí)現(xiàn)之外,每個(gè)實(shí)現(xiàn)都支持空鍵和值。并不是所有的實(shí)現(xiàn)都是作為一個(gè)Map實(shí)現(xiàn)的(特別是一些Multimap實(shí)現(xiàn)使用自定義哈希表來(lái)最小化開(kāi)銷(xiāo)。)最新面試題大家可以在Java面試庫(kù)小程序在線(xiàn)刷題。
在線(xiàn)演示源碼
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/MultimapTest.java
推薦一個(gè) Spring Boot 基礎(chǔ)教程及實(shí)戰(zhàn)示例:
https://github.com/javastacks/spring-boot-best-practice
BiMap 雙向映射
1、將值映射回鍵的傳統(tǒng)方法是維護(hù)兩個(gè)獨(dú)立的映射,并使它們保持同步,但這很容易產(chǎn)生錯(cuò)誤,并且當(dāng)映射中已經(jīng)存在一個(gè)值
Map?nameToId?=?Maps.newHashMap();
Map?idToName?=?Maps.newHashMap();
nameToId.put("Bob",?42);
idToName.put(42,?"Bob");
2、BiMap 提供了多種實(shí)現(xiàn):
| 鍵值映射實(shí)現(xiàn) | 值鍵映射實(shí)現(xiàn) | 對(duì)應(yīng)BiMap |
|---|---|---|
| HashMap | HashMap | HashBiMap |
| ImmutableMap | ImmutableMap | ImmutableBiMap |
| EnumMap | EnumMap | EnumBiMap |
| EnumMap | HashMap | EnumHashBiMap |
在線(xiàn)演示源碼:
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/BiMapTest.java
Table 表結(jié)構(gòu)數(shù)據(jù)
1、當(dāng)試圖一次在多個(gè)鍵上建立索引時(shí),您將得到類(lèi)似 Map的代碼,這很難看,而且使用起來(lái)很尷尬。Guava 提供了一個(gè)新的集合類(lèi)型 Table,它支持任何“row”類(lèi)型和“column”類(lèi)型的這個(gè)用例。
2、Table 提供了多種實(shí)現(xiàn):
HashBasedTable:基本上是由 HashMap支持的。> TreeBasedTable:基本上是由 TreeMap支撐的。> ImmutableTable ArrayTable:要求在構(gòu)造時(shí)指定行和列的完整范圍,但在表密集時(shí)由二維數(shù)組支持以提高速度和內(nèi)存效率,ArrayTable的工作原理與其他實(shí)現(xiàn)有些不同
在線(xiàn)演示源碼:
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/TableTest.java
ClassToInstanceMap 類(lèi)型映射到實(shí)例
1、有時(shí) key 并不是單一的類(lèi)型,而是多種類(lèi)型,Guava 為此提供了 ClassToInstanceMap,key 可以是多種類(lèi)型,value 是此類(lèi)型的實(shí)例。
2、ClassToInstanceMap 的實(shí)現(xiàn)有:MutableClassToInstanceMap 和 ImmutableClassToInstanceMap 的實(shí)現(xiàn)。
在線(xiàn)演示源碼:
https://github.com/wangmaoxiong/src/main/java/com/wmx/guava/ClassToInstanceMapTest.java
JDK 集合輔助工具類(lèi)
1、任何有 JDK 集合框架經(jīng)驗(yàn)的程序員都知道并喜歡其中提供的實(shí)用程序 java.util.Collections,Guava 提供了許多適用于集合的靜態(tài)方法實(shí)用程序。
| 接口 | 屬于 JDK 還是 Guava | 對(duì)應(yīng) Guava API |
|---|---|---|
| Collection | JDK | Collections2 |
| List | JDK | Lists |
| Set | JDK | Sets |
| SortedSet | JDK | Sets |
| Map | JDK | Maps |
| SortedMap | JDK | Maps |
| Queue | JDK | Queues |
| Multiset | Guava | Multisets |
| Multimap | Guava | Multimaps |
| BiMap | Guava | Maps |
| Table | Guava | Tables |
Lists 在線(xiàn)演示:
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/ListsTest.java
Sets 在線(xiàn)演示:
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/SetsTest.java
JDK 基本類(lèi)型輔助工具類(lèi)
1、Guava 為 Java JDK 的基本類(lèi)型提供了實(shí)用程序類(lèi):
| 基本類(lèi)型 | Guava 輔助工具類(lèi) |
|---|---|
| byte | Bytes, SignedBytes, UnsignedBytes |
| short | Shorts |
| int | Ints, UnsignedInteger, UnsignedInts |
| long | Longs, UnsignedLong, UnsignedLongs |
| float | Floats |
| double | Doubles |
| char | Chars |
| boolean | Booleans |
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/IntsTest.java
https://github.com/src/main/java/com/wmx/guava/DoublesTest.java
https://github.com/src/main/java/com/wmx/guava/BooleansTest.java
JDK 字符串輔助工具類(lèi)
1、Strings 類(lèi)中提供了少數(shù)幾個(gè)常用的符串實(shí)用程序。
在線(xiàn)演示源碼:https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/StringsTest.java
2、Joiner 是連接器,用于連接 java.lang.Iterable、java.util.Iterator、java.lang.Object[] 中的元素。
在線(xiàn)演示源碼:https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/JoinerTest.java
3、Splitter 是分割器,用于分割字符序列 java.lang.CharSequence。
在線(xiàn)演示源碼:https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/SplitterTest.java
4、CharMatcher 字符匹配器,用于匹配字符,可以將 CharMatcher 視為代表一類(lèi)特定的字符,如數(shù)字或空白。注意:CharMatcher 只處理 char 值。
在線(xiàn)演示源碼:https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/guava/CharMatcherTest.java
Stopwatch 秒表
1、google 的秒表 Stopwatch 相比 Spring framewrk core 包 和 apache commons lang3 包的秒表是最方便使用的。
/**
?* Stopwatch createStarted():創(chuàng)建(并啟動(dòng))一個(gè)新的秒表,使用 System#nanoTime 來(lái)作為其時(shí)間源。
?* Stopwatch createUnstarted():創(chuàng)建(但不啟動(dòng))一個(gè)新的秒表,使用 System#nanoTime 來(lái)作為其時(shí)間源。
?* long elapsed(TimeUnit desiredUnit):返回此秒表上顯示的當(dāng)前已用時(shí)間,以所需的時(shí)間單位表示,任何分?jǐn)?shù)向下舍入
?* boolean isRunning():如果已在此秒表上調(diào)用start()},并且自上次調(diào)用start()以來(lái)未調(diào)用stop(),則返回true
?* Stopwatch reset():將此秒表的運(yùn)行時(shí)間設(shè)置為零,并將其置于停止?fàn)顟B(tài)。
?* Stopwatch start():?jiǎn)?dòng)秒表,如果秒表已經(jīng)在運(yùn)行,則 IllegalStateException
?* Stopwatch stop():停止秒表,將來(lái)的讀取將返回到目前為止經(jīng)過(guò)的固定持續(xù)時(shí)間。
?* tring toString():返回當(dāng)前運(yùn)行時(shí)間的字符串表示形式,比如 2.588 s,106.8 ms
?*/
@Test
public?void?testStopwatch()?throws?InterruptedException?{
????SecureRandom?secureRandom?=?new?SecureRandom();
????Stopwatch?stopwatch?=?Stopwatch.createStarted();
????int?nextInt?=?secureRandom.nextInt(2000);
????System.out.println("任務(wù)1預(yù)算耗時(shí):"?+ nextInt);//任務(wù)1預(yù)算耗時(shí):81
????TimeUnit.MILLISECONDS.sleep(nextInt);
????System.out.println("\t任務(wù)1實(shí)際耗時(shí):"?+?stopwatch.elapsed(TimeUnit.MILLISECONDS)?+?"(毫秒)");//?任務(wù)1實(shí)際耗時(shí):563(毫秒)
????stopwatch.reset().start();
????nextInt?=?secureRandom.nextInt(4000);
????System.out.println("任務(wù)2預(yù)算耗時(shí):"?+ nextInt);//任務(wù)2預(yù)算耗時(shí):1591
????TimeUnit.MILLISECONDS.sleep(nextInt);
????System.out.println("\t任務(wù)2實(shí)際耗時(shí):"?+ stopwatch.toString());//?任務(wù)2實(shí)際耗時(shí):1.592 s
????stopwatch.reset().start();
????nextInt?=?secureRandom.nextInt(3000);
????System.out.println("任務(wù)3預(yù)計(jì)耗時(shí):"?+ nextInt);//任務(wù)3預(yù)計(jì)耗時(shí):1964
????TimeUnit.MILLISECONDS.sleep(nextInt);
????System.out.println("\t任務(wù)3實(shí)際耗時(shí):"?+ stopwatch.stop().toString());//?任務(wù)3實(shí)際耗時(shí):1.965 s
}
覺(jué)得不錯(cuò),就用起來(lái)吧!
版權(quán)聲明:本文為CSDN博主「蚩尤后裔」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/wangmx1993328/article/details/103533060
????
往 期 推 薦
1、拖動(dòng)文件就能觸發(fā)7-Zip安全漏洞,波及所有版本
3、一次 SQL 查詢(xún)優(yōu)化原理分析:900W+ 數(shù)據(jù),從 17s 到 300ms
4、Redis數(shù)據(jù)結(jié)構(gòu)為什么既省內(nèi)存又高效?
點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看





