經常使用的 Java 工具類之 Guava 使用

上篇咱們介紹 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 Collections

Guava 爲集合類提供相關工具類以及一些集合的新類型,方便咱們平常開發。github

集合新工具類- Lists

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));//字符串是否都爲數字

複製代碼

Stopwatch

有時候咱們須要知道方法的調用時間,這個時候咱們每每使用下列代碼:

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));
複製代碼

參考文檔

  1. Guava 中文翻譯
  2. Guava wiki
相關文章
相關標籤/搜索