Guava的Lists與Maps

Lists

Lists類主要提供了對List類的子類構造以及操作的靜態方法。在Lists類中支持構造ArrayList、LinkedList以及newCopyOnWriteArrayList對象的方法。

其中提供了以下構造ArrayList的函數:下面四個構造一個ArrayList對象,但是不顯式的給出申請空間的大小:

newArrayList()
newArrayList(E... elements)
newArrayList(Iterable<? extends E> elements)
newArrayList(Iterator<? extends E> elements)

以下兩個函數在構造ArrayList對象的時候給出了需要分配空間的大小:

newArrayListWithCapacity(int initialArraySize)
newArrayListWithExpectedSize(int estimatedSize)

如果你事先知道元素的個數,可以用newArrayListWithCapacity函數;如果你不能確定元素的個數,可以用newArrayListWithExpectedSize函數,在newArrayListWithExpectedSize函數里面調用了computeArrayListCapacity(int arraySize)函數,其實現如下:

@VisibleForTesting static int computeArrayListCapacity(int arraySize) {
    checkArgument(arraySize >= 0);
 
    // TODO(kevinb): Figure out the right behavior, and document it
    return Ints.saturatedCast(5L + arraySize + (arraySize / 10));
  }

返回的容量大小為5L + arraySize + (arraySize / 10),當arraySize比較大的時候,給定大小和真正分配的容量之比為10/11。

Lists類還支持構造LinkedList、newCopyOnWriteArrayList對象,其函數接口為:

newLinkedList()
newLinkedList(Iterable<? extends E> elements)
 
newCopyOnWriteArrayList()
newCopyOnWriteArrayList(Iterable<? extends E> elements)

我們還可以將兩個(或三個)類型相同的數據存放在一個list中,這樣可以傳入到只有一個參數的函數或者需要減少參數的函數中,這些函數如下:

asList(@Nullable E first, E[] rest)
asList(@Nullable E first, @Nullable E second, E[] rest)

Lists類中transform函數可以根據傳進來的function對fromList進行相應的處理,并將處理得到的結果存入到新的list對象中,這樣有利于我們進行分析,函數接口如下:

public static <F, T> List<T> transform(
      List<F> fromList, Function<? super F, ? extends T> function)

但是使用這個類的是需要注意一點,轉化之后的集合,不再支持 add 等修改集合的方法。如果使用遍歷方法去修改集合里面對象,并不會產生效果。原因在于轉化之后的 List 只是原 List 的視圖而已,所以獲取轉化后集合里的對象,比如調用 get 時,每次調用會是會使用 function 轉化方法。

使用例子:

Function<String, Integer> strlen = new Function<String, Integer>() {
    public Integer apply(String from) {
        Preconditions.checkNotNull(from);
        return from.length();
    }
};
List<String> from = Lists.newArrayList("abc", "defg", "hijkl");
List<Integer> to = Lists.transform(from, strlen);
for (int i = 0; i < from.size(); i++) {
    System.out.printf("%s has length %d\n", from.get(i), to.get(i));
}
 
 
Function<String, Boolean> isPalindrome = new Function<String, Boolean>() {
    public Boolean apply(String from) {
        Preconditions.checkNotNull(from);
        return new StringBuilder(from).reverse().toString().equals(from);
    }
};
from = Lists.newArrayList("rotor", "radar", "hannah", "level", "botox");
List<Boolean> to1 = Lists.transform(from, isPalindrome);
for (int i = 0; i < from.size(); i++) {
    System.out.printf("%s is%sa palindrome\n", from.get(i), to1.get(i) ? " " : " NOT ");
}
// changes in the "from" list are reflected in the "to" list
System.out.printf("\nnow replace hannah with megan...\n\n");
from.set(2, "megan");
for (int i = 0; i < from.size(); i++) {
    System.out.printf("%s is%sa palindrome\n", from.get(i), to1.get(i) ? " " : " NOT ");
}

Lists還可以將傳進來的String或者CharSequence分割為單個的字符,并存入到一個新的List對象中返回,如下:

ImmutableList<Character> wyp = Lists.charactersOf("wyp");
System.out.println(wyp);

將List對象里面的數據順序反轉可以用reverse函數實現,取得List對象里面的子序列可以用subList函數實現。

Maps

HashMap

Map<String, String> aNewMap = Maps.newHashMap();

ImmutableMap

創建不可變Map:

@Test
public void whenCreatingImmutableMap_thenCorrect() {
    Map<String, Integer> salary = ImmutableMap.<String, Integer> builder()
            .put("John", 1000)
            .put("Jane", 1500)
            .put("Adam", 2000)
            .put("Tom", 2000)
            .build();

    assertEquals(1000, salary.get("John").intValue());
    assertEquals(2000, salary.get("Tom").intValue());
}

salary初始化后,不能在更改,調用put方法會報java.lang.UnsupportedOperationException異常。

SortedMap

本節我們看下創建SortMap,下面示例我們使用Guava相應builder創建一個有序map:

@Test
public void whenUsingSortedMap_thenKeysAreSorted() {
    ImmutableSortedMap<String, Integer> salary = new ImmutableSortedMap
      .Builder<String, Integer>(Ordering.natural())
      .put("John", 1000)
      .put("Jane", 1500)
      .put("Adam", 2000)
      .put("Tom", 2000)
      .build();

    assertEquals("Adam", salary.firstKey());
    assertEquals(2000, salary.lastEntry().getValue().intValue());
}

我們看到salary中記錄按照字母進行排序。

BiMap

本節我們討論如何使用BiMap,BiMap也可以反向把值映射到鍵,只要確保值唯一。

下面示例中,我們創建BiMap,并使用其inverse()方法:

@Test
public void whenCreateBiMap_thenCreated() {
    BiMap<String, Integer> words = HashBiMap.create();
    words.put("First", 1);
    words.put("Second", 2);
    words.put("Third", 3);

    assertEquals(2, words.get("Second").intValue());
    assertEquals("Third", words.inverse().get(3));
}

Multimap

本節我們使用Multimap ,對每個鍵關聯多個值:

@Test
public void whenCreateMultimap_thenCreated() {
    Multimap<String, String> multimap = ArrayListMultimap.create();
    multimap.put("fruit", "apple");
    multimap.put("fruit", "banana");
    multimap.put("pet", "cat");
    multimap.put("pet", "dog");

    assertThat(multimap.get("fruit"), containsInAnyOrder("apple", "banana"));
    assertThat(multimap.get("pet"), containsInAnyOrder("cat", "dog"));
}

Multimap的get方法返回 java.util.Collection,上述測試代碼除了junit,還需要增加:

testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'

Table

當需要多余一個鍵索引值時,需要Table。下面示例中,我們使用Table存儲城市之間距離:

@Test
public void whenCreatingTable_thenCorrect() {
    Table<String,String,Integer> distance = HashBasedTable.create();
    distance.put("London", "Paris", 340);
    distance.put("New York", "Los Angeles", 3940);
    distance.put("London", "New York", 5576);

    assertEquals(3940, distance.get("New York", "Los Angeles").intValue());
    assertThat(distance.columnKeySet(), 
      containsInAnyOrder("Paris", "New York", "Los Angeles"));
    assertThat(distance.rowKeySet(), containsInAnyOrder("London", "New York"));
}

ClassToInstanceMap

把類作為鍵映射至對象:

@Test
public void whenCreatingClassToInstanceMap_thenCorrect() {
    ClassToInstanceMap<Number> numbers = MutableClassToInstanceMap.create();
    numbers.putInstance(Integer.class, 1);
    numbers.putInstance(Double.class, 1.5);

    assertEquals(1, numbers.get(Integer.class));
    assertEquals(1.5, numbers.get(Double.class));
}

Integer,Double都繼承至Number,ClassToInstanceMap讓不同的子類作為key。

Multimap分組

通過Multimap對List進行分組,下面示例中是使用Multimaps.index方法依據list元素的長度進行分組。

@Test
public void whenGroupingListsUsingMultimap_thenGrouped() {
    List<String> names = Lists.newArrayList("John", "Adam", "Tom");
    Function<String,Integer> func = new Function<String,Integer>(){
        public Integer apply(String input) {
            return input.length();
        }
    };
    Multimap<Integer, String> groups = Multimaps.index(names, func);

    assertThat(groups.get(3), containsInAnyOrder("Tom"));
    assertThat(groups.get(4), containsInAnyOrder("John", "Adam"));
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380