上篇咱們介紹 Apache 的相關工具類的使用,此次咱們介紹 Google 的工具類 Guava。java
The Guava project contains several of Google's core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth. Each of these tools really do get used every day by Googlers, in production services.
正如 Guava wiki 介紹,Guava 的是 Google 的工具類,提供字符串處理,I/O,集合類相關操做。若是你去翻看 JDK8 的代碼,能夠看到其不少新增類,Guava 以前其實已經實現,不少類名也都同樣,能夠看出 Guava 的影響。下面開始介紹 Guava 的使用。git
Guava 爲集合類提供相關工具類以及一些集合的新類型,方便咱們平常開發。github
Lists.newArrayList()
使用靜態方法直接建立 List 集合。api
// 在JDK 7以前,構造新的集合時咱們須要重複聲明範型
List<String> testList = new ArrayList<String>();
// 使用 Lists 以後咱們可使用靜態方法自動推導
List<String> testList1 = Lists.newArrayList();
// 若是須要指定初始大小
List<String> capicatyList = Lists.newArrayListWithCapacity(100);
複製代碼
Lists.partition()
按照指定大小拆分大集合app
// 定義一個 10W 數量的集合
List<String> largeList = Lists.newArrayListWithCapacity(100 * 1000);
// 拆分紅 100 個集合數量 1000 的大小的小集合
List<List<String>> smallLists = Lists.partition(largeList, 1000);
複製代碼
Lists.transform
將集合數據類型轉化成其餘類型的集合ide
List<String> largeList = Lists.newArrayListWithCapacity(100 * 1000);
List<List<String>> smallLists = Lists.partition(largeList, 1000);
// function 方法能夠執行轉化動做,將類型 A 的對象 轉化爲 B 對象
List<Integer> a = Lists.transform(largeList, new Function<String, Integer>() {
@Override
public Integer apply(String input) {
return input.hashCode() + 111;
}
});
複製代碼
可是使用這個類的是須要注意一點,轉化以後的集合,再也不支持 add 等修改集合的方法。若是使用遍歷方法去修改集合裏面對象,並不會產生效果。緣由在於轉化以後的 List 只是原 List 的視圖而已,因此獲取轉化後集合裏的對象,好比調用 get 時,每次調用會是會使用 function 轉化方法。工具
Returns a list that applies function to each element of fromList. The returned list is a transformed view of fromList; changes to fromList will be reflected in the returned list and vice versa
Guava transform 問題google
Multiset 若是光看類名的話,可能會覺得其只是實現 Set 接口的新類。其實否則,這個類實現是相似如下功能:spa
Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
Integer count = counts.get(word);
if (count == null) {
counts.put(word, 1);
} else {
counts.put(word, count + 1);
}
}
複製代碼
若是存在上述需求,咱們再也不須要本身笨拙且容易出錯的代碼。如今咱們能夠看若是使用 Multiset 實現上述代碼。pwa
Multiset<String> multiset = HashMultiset.create();
// 統計每次單詞出現的次數
for (String word : words) {
multiset.add(word);
}
// 輸出單詞的輸出次數
for (String word : multiset.elementSet()) {
multiset.count(word);
}
複製代碼
有時候咱們須要實現一個鍵與多個值映射的功能,這時候咱們可能會使用 Map<K, List<V>>
,可是這種方法可能在實現中不當心就致使各類名空指針異常等。下面咱們使用 Multimap
實現這種需求。
Multimap<Integer, People> multimap = ArrayListMultimap.create();
// 統計同一年紀的 People 對象
for (People people : peopleList) {
multimap.put(people.getAge(), people);
}
// 輸出統計結果
for (Integer key : multimap.keySet()) {
List<People> peoples = Lists.newArrayList(multimap.get(key));
System.out.println(peoples);
}
複製代碼
Joiner
實現字符串鏈接功能。
// 實現的鏈接器將忽略 Null
Joiner joiner = Joiner.on(";").skipNulls();
// 字符串爲Harry;Ron;Hermione
return joiner.join("Harry", null, "Ron", "Hermione");
複製代碼
Splitter
字符串拆分器,實現字符串按照指定字符拆分功能
// 如下拆分將將結果去除首部與尾部空格,以及去除空字符串。因此拆分以後結果爲 foo bar qux
Splitter.on(',')
.trimResults()
.omitEmptyStrings()
.split("foo,bar,, qux");
複製代碼
CharMatcher
字符串匹配器,實現匹配篩選等動做。
String string = "12312ada[21`443#$$#@ asda";
System.out.println(CharMatcher.DIGIT.retainFrom(string));//只保留數字 1231221443
System.out.println(CharMatcher.JAVA_LETTER_OR_DIGIT.replaceFrom(string, "*")); // 數字與字母使用*號代替
System.out.println(CharMatcher.DIGIT.matchesAllOf(string));//字符串是否都爲數字
複製代碼
有時候咱們須要知道方法的調用時間,這個時候咱們每每使用下列代碼:
long startTime = System.currentTimeMillis();
// 業務方法調用
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
複製代碼
這種寫法若是須要轉化時間單位咱們還須要通過各類換算,若是須要計算多個調用時間,時間定義每每比較雜亂。咱們可使用 Stopwatch
代替。
Stopwatch stopwatch = Stopwatch.createUnstarted();
// 開始計量時間
stopwatch.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 中止計量時間
stopwatch.stop();
// 根據輸入時間單位獲取相應的時間
System.out.println(stopwatch.elapsed(TimeUnit.SECONDS));
複製代碼