guava學習--集合1


Lists:

其內部使用了靜態工廠方法代替構造器,提供了許多用於List子類構造和操作的靜態方法,我們簡單的依次進行說明,如下:

newArrayList():構造一個可變的、空的ArrayList實例。

newArrayList(E... elements):構造一個可變的包含傳入元素elements的ArrayList實例。

newArrayList(Iterable<? extends E> elements):構造一個可變的包含傳入元素elements的ArrayList實例。

newArrayListWithCapacity( int initialArraySize):構造一個分配 指定空間大小的ArrayList實例。

newArrayListWithExpectedSize( int estimatedSize):構造一個期望長度為estimatedSize的ArrayList實例。

newLinkedList():構造一個空的LinkedList實例。

newLinkedList( Iterable<? extends E> elements):構造一個包含傳入元素elements的LinkedList實例。

newCopyOnWriteArrayList():構造一個空的CopyOnWriteArrayList實例。

newCopyOnWriteArrayList( Iterable<? extends E> elements):構造一個包含傳入元素elements的CopyOnWriteArrayList實例。

asList(@Nullable E first, E[] rest):返回一個不可變的List,其中包含指定的第一個元素和附加的元素數組組成,修改這個數組將反映到返回的List上。

asList( @Nullable E first, @Nullable E second, E[] rest): 返回一個不可變的List,其中包含指定的第一個元素、第二個元素和附加的元素數組組成,修改這個數組將反映到返回的List上。

transform( List fromList, Function<? super F, ? extends T> function):根據傳進來的function對fromList進行相應的處理,並將處理得到的結果存入到新的list對象中返回。

partition(List list, int size):根據size傳入的List進行切割,切割成符合要求的小的List,並將這些小的List存入一個新的List對象中返回。

charactersOf(String string)、charactersOf(CharSequence sequence):將傳進來的String或者CharSequence分割為單個的字符,並存入到一個ImmutableList對象中返回。 (ImmutableList:一個高性能、不可變的、隨機訪問列表的實現 )

reverse(List list):返回一個傳入List內元素倒序后的List。

接下來,我們通過下面的示例代碼,來繼續加深對Lists的理解,代碼如下:

/**
 * Lists:處理List實例的實用類
 * User: Realfighter
 * Date: 2014/8/31
 * Time: 22:45
 */
public class ListsTest { @Test public void testLists() { /** * 一些構造List實例的方法很簡單 * 如:newArrayList(),newLinkedList()等 * 這里不再贅述 */ String str = "i love u";//測試用 String[] strs = {"i like u", "i miss u"};//測試用 /** * asList:返回一個不可變的List * 其中包含指定的第一個元素和附加的元素數組組成 * 修改這個數組將反映到返回的List上 */ List<String> list = Lists.asList(str, strs); System.out.println(list); //[i love u, i like u, i miss u] strs[1] = "i hate u";//對strs數組的修改會反映到List中 System.out.println(list);//[i love u, i like u, i hate u] /** * transform:根據傳進來的function對fromList進行相應的處理 * 並將處理得到的結果存入到新的list對象中返回 */ List<String> newList = Lists.transform(list, new Function<String, String>() { @Override public String apply(String input) { //這里簡單的對集合中的元素轉換為大寫 return input.toUpperCase(); } }); System.out.println(newList);//[I LOVE U, I LIKE U, I HATE U] /** * partition:根據size傳入的List進行切割,切割成符合要求的小的List * 並將這些小的List存入一個新的List對象中返回 */ List<List<String>> lists = Lists.partition(list, 2); System.out.println(lists);//[[i love u, i like u], [i hate u]] /** * charactersOf:將傳進來的String或者CharSequence分割為單個的字符 * 並存入到一個ImmutableList對象中返回 * ImmutableList:一個高性能、不可變的、隨機訪問列表的實現 */ ImmutableList<Character> characters = Lists.charactersOf("realfighter"); System.out.println(characters);//[r, e, a, l, f, i, g, h, t, e, r] /** * reverse:返回一個傳入List內元素倒序后的List */ List<String> reverse = Lists.reverse(list); System.out.println(reverse);//[i hate u, i like u, i love u] } }

 

Sets:

Sets內部使用了靜態工廠方法代替構造器,提供了許多用於Set子類構造和操作的靜態方法,我們簡單的依次進行說明,如下:

immutableEnumSet( E anElement, E... otherElements):返回一個包含給定枚舉元素的不可變的Set實例。

immutableEnumSet( Iterable<E> elements):返回一個包含給定枚舉元素的不可變的Set實例。

newEnumSet(Iterable<E> iterable,Class<E> elementType):返回一個包含給定元素的EnumSet實例,與EnumSet#copyOf(Collection)方法不同,當給定集合為 空的時候,不會產生異常,它可以轉換任何實現了Iterable接口的類,不僅僅是Collection。它會先根據傳入的元素類型創建一個空的 EnumSet,再把給定的元素添加到EnumSet返回。

newHashSet():返回一個可變的空的HashSet實例。

newHashSet(E... elements):返回一個可變買的HashSet包含給定的元素。

newHashSetWithExpectedSize(int expectedSize):構造一個期望長度為expectedSize的HashSet實例。

newHashSet(Iterable<? extends E> elements):返回一個可變的HashSet包含給定的元素,給定元素實現Iterable接口。

newHashSet(Iterator<? extends E> elements):返回一個可變的HashSet包含給定的元素,給定元素實現Iterator接口。

newConcurrentHashSet():創建一個線程安全的Set,由ConcurrentHashMap的實例支持,因此進行了相同的並發性擔保,與HashSet不同的是,這個Set不允許null元素,該Set是可序列化的。

newConcurrentHashSet( Iterable<? extends E> elements):創建一個線程安全的Set,包含給定的元素,由ConcurrentHashMap的實例支持,因此進行了相同的並發性擔保,與 HashSet不同的是,這個Set不允許null元素,該Set是可序列化的。

newLinkedHashSet():創建一個可變的、空的LinkedHashSet實例。

newLinkedHashSetWithExpectedSize( int expectedSize):構造一個期望長度為expectedSize的LinkedHashSet實例。

newLinkedHashSet( Iterable<? extends E> elements):構造一個包含給定元素的LinkedHashSet實例。

newTreeSet():返回一個可變的空的TreeSet實例。

newTreeSet( Iterable<? extends E> elements):返回一個可變的包含給定元素的TreeSet實例。

newTreeSet(Comparator<? super E> comparator):創建一個具有給定的比較器可變TreeSet的實例。

newIdentityHashSet():創建一個空的Set,使用特性來確定是否相等。

newCopyOnWriteArraySet():創建一個空的CopyOnWriteArraySet實例。

newCopyOnWriteArraySet( Iterable<? extends E> elements):創建一個包含給定元素的CopyOnWriteArraySet實例。

complementOf(Collection<E> collection):創建一個EnumSet包括不屬於指定集合中的所有枚舉值。

complementOf( Collection<E> collection, Class<E> type):創建一個EnumSet包括不屬於指定集合中的所有枚舉值。

newSetFromMap(Map<E, Boolean> map):返回一個由給定map支持的Set。

union( final Set<? extends E> set1, final Set<? extends E> set2):返回兩個set集合的並集的不可修改SetView。(若A和B是集合,則A和B並集是有所有A的元素和所有B的元素,而沒有其他元素的集 合)

intersection( final Set<E> set1, final Set<?> set2):返回兩個set集合的交集的不可修改SetView。(兩個集合A 和 集合B 的交集是指含有所有既屬於 A 又屬於 B 的元素,而沒有其他元素的集合)

difference( final Set<E> set1, final Set<?> set2):返回兩個set集合的差的不可修改SetView。(A,B是兩個集合,則所有屬於A且不屬於B的元素構成的集合,叫做A與B的差集)

symmetricDifference( Set<? extends E> set1, Set<? extends E> set2):返回兩個set集合的對稱差的不可修改SetView。(對稱差,即兩個集合的對稱差是只屬於其中一個集合,而不屬於另一個集合的元素組成的 集合)

filter(Set<E> unfiltered, Predicate<? super E> predicate):返回傳入Set集合unfiltered中滿足給定Predicate的元素集合Set。

filter( SortedSet<E> unfiltered, Predicate<? super E> predicate):返回傳入SortedSet集合unfiltered中滿足給定Predicate的元素集合SortedSet。

filter( NavigableSet<E> unfiltered, Predicate<? super E> predicate):返回傳入NavigableSet集合unfiltered中滿足給定Predicate的元素集合NavigableSet。

cartesianProduct( List<? extends Set<? extends B>> sets):返回通過從各給定集中選擇一個元素所形成每一個可能的集合。

cartesianProduct( Set<? extends B>... sets):返回通過從各給定集中選擇一個元素所形成每一個可能的集合。

powerSet(Set<E> set):返回一個set,包含給定set的所有可能父級集合。

unmodifiableNavigableSet( NavigableSet<E> set):返回指定NavigableSet的不可修改視圖。

synchronizedNavigableSet( NavigableSet<E> navigableSet):返回一個同步的(線程安全的)NavigableSet,由指定的NavigableSet支持。

Sets類中提供的方法很多,我們這里對其中的一些重點和特別的方法做一些示例學習,其他的方法不再贅述,示例代碼如下:

/**
 * Sets:處理Set實例的實用類
 * User: Realfighter
 * Date: 2014/9/3
 * Time: 20:00
 */
public class SetsTest { Set<Integer> set1;//測試用 Set<Integer> set2;//測試用 /** * 初始化測試集合 */ @Before public void setUp() { set1 = Sets.newHashSet(1, 2, 3, 4, 5); set2 = Sets.newHashSet(1, 3, 5, 7, 9); } /** * filter:返回傳入Set集合unfiltered中滿足給定Predicate的元素集合Set */ @Test public void testFilter() { Set<String> set = Sets.newHashSet("i like u", "i miss u", "i love u"); Predicate<String> predicate = new Predicate<String>() { @Override public boolean apply(String input) { //過濾包含字母l的元素 return input.contains("l"); } }; //輸出:[i like u, i love u] System.out.println(Sets.filter(set, predicate)); } /** * difference:返回兩個set集合的差的不可修改SetView * A,B是兩個集合,則所有屬於A且不屬於B的元素構成的集合,叫做A與B的差集 */ @Test public void testDifference() { //輸出:[2, 4] System.out.println(Sets.difference(set1, set2)); } /** * symmetricDifference:返回兩個set集合的對稱差的不可修改SetView * 對稱差,即兩個集合的對稱差是只屬於其中一個集合,而不屬於另一個集合的元素組成的集合 */ @Test public void testSymmetricDifference() { //輸出:[2, 4, 9, 7] System.out.println(Sets.symmetricDifference(set1, set2)); } /** * intersection:返回兩個set集合的交集的不可修改SetView * 兩個集合A和集合B的交集是指含有所有既屬於A又屬於B的元素,而沒有其他元素的集合 */ @Test public void testIntersection() { //輸出:[1, 3, 5] System.out.println(Sets.intersection(set1, set2)); } /** * Union:返回兩個set集合的並集的不可修改SetView * 若A和B是集合,則A和B並集是有所有A的元素和所有B的元素,而沒有其他元素的集合 */ @Test public void testUnion() { //輸出:[1, 2, 3, 4, 5, 9, 7] System.out.println(Sets.union(set1, set2)); } /** * cartesianProduct:返回通過從各給定集中選擇一個元素所形成每一個可能的集合 */ @Test public void testCartesianProduct() { Set<String> set1 = Sets.newHashSet("i love u", "i hate u"); Set<String> set2 = Sets.newHashSet("tom", "jerry"); Set<List<String>> sets = Sets.cartesianProduct(set1, set2); //輸出:[[i hate u, tom], [i hate u, jerry], [i love u, tom], [i love u, jerry]] System.out.println(sets); } /** * powerSet:返回一個set,包含給定set的所有可能父級集合 */ @Test public void testPowerSet() { Set<String> set1 = Sets.newHashSet("i love u", "i hate u"); Set<Set<String>> sets = Sets.powerSet(set1); for (Set<String> set : sets) { System.out.print(set); } //輸出:[][i hate u][i love u][i hate u, i love u] } }


Maps:

immutableEnumMap( Map<K, ? extends V> map):返回包含給定項的不可變映射實例。

newHashMap():構造一個可變的空的HashMap實例。

newHashMapWithExpectedSize(int expectedSize):構造一個期望長度為expectedSize的HashMap實例。

newHashMap( Map<? extends K, ? extends V> map):構造一個與給定map有相同映射關系的可變HashMap實例。

newLinkedHashMap():構造一個可變的、空的、插入排序的LinkedHashMap實例。

newLinkedHashMap( Map<? extends K, ? extends V> map):構造一個可變的、插入排序的、與給定map有相同映射關系的LinkedHashMap實例。

newConcurrentMap():返回一個通用的ConcurrentMap實例,支持ConcurrentMap接口的所有可選操作,它不允許null鍵或值,它是可序列化的。

newTreeMap():構造一個可變的、空的TreeMap實例。

newTreeMap(SortedMap<K, ? extends V> map):構造一個可變的、與給定SortedMap有相同映射關系的TreeMap實例。

newTreeMap( @Nullable Comparator<C> comparator):構造一個可變的、空的、使用給定比較器的TreeMap實例。

newEnumMap(Class<K> type):構造一個具有給定鍵類型的EnumMap實例。

newEnumMap( Map<K, ? extends V> map):構造一個與給定map有相同映射關系的EnumMap實例。

newIdentityHashMap():構造一個IdentityHashMap實例。

difference( Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right):返回兩個給定map之間的差異。

difference( Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right, Equivalence<? super V> valueEquivalence):返回兩個給定map之間的差異,通過所提供的valueEquivalence進行等值比較。

difference( SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right):返回兩個已排序的Map之間的差異,通過給定left的比較器。

asMap( Set<K> set, Function<? super K, V> function):返回一個活動的map,鍵值為給定的set中的值,value為通過給定Function計算后的值。

asMap( SortedSet<K> set, Function<? super K, V> function):返回有序Set集合的map表示,根據給定的Function從給定的Set中映射鍵值。

asMap( NavigableSet<K> set, Function<? super K, V> function):返回NavigableSet集合的map表示,根據給定的Function從給定的Set中映射鍵值。

toMap(Iterable<K> keys,Function<? super K, V> valueFunction)、toMap(Iterator<K> keys,Function<? super K, V> valueFunction):返回一個不可變的ImmutableMap實例,其鍵值為給定keys中去除重復值后的值,其值為鍵被計算了 valueFunction后的值。

uniqueIndex(Iterable<V> values, Function<? super V, K> keyFunction)、uniqueIndex(Iterator<V> values, Function<? super V, K> keyFunction):返回一個不可變的ImmutableMap實例,其值為按照給定順序的給定的values值,鍵值為相應的值經過給定 Function計算后的值。

fromProperties(Properties properties):通過給定的Properties實例,返回一個不可變的ImmutableMap實例。

immutableEntry(@Nullable K key, @Nullable V value):通過給定的key/value,返回一個不可變的map映射。

asConverter(final BiMap<A, B> bimap):返回一個Converter轉換器,通過bimap.get()方法轉換值,它的逆視圖使用bimap.inverse().get()方法轉換值。

synchronizedBiMap(BiMap<K, V> bimap):返回一個同步的(線程安全)的bimap,由給定的bimap支持。

unmodifiableBiMap( BiMap<? extends K, ? extends V> bimap):返回給定的bimap的不可修改的BiMap表示。

transformValues( Map<K, V1> fromMap, Function<? super V1, V2> function):返回一個map映射,其鍵值為給定fromMap的鍵值,其value為給定formMap中value通過Function轉換后 的值。

transformValues( SortedMap<K, V1> fromMap, Function<? super V1, V2> function):返回一個SortedMap映射,其鍵值為給定fromMap的鍵值,其value為給定formMap中value通過 Function轉換后的值。

transformValues( NavigableMap<K, V1> fromMap, Function<? super V1, V2> function):返回一個NavigableMap映射,其鍵值為給定fromMap的鍵值,其value為給定formMap中value通過 Function轉換后的值。

transformEntries( Map<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer):返回一個map映射,其Entry為給定fromMap.Entry通過給定EntryTransformer轉換后的值。

transformEntries(SortedMap<K, V1> fromMap, EntryTransformer<? super K, ? super V1, V2> transformer):返回一個SortedMap映射,其Entry為給定fromMap.Entry通過給定EntryTransformer轉 換后的值。

transformEntries( final NavigableMap<K, V1> fromMap,EntryTransformer<? super K, ? super V1, V2> transformer):返回一個NavigableMap映射,其Entry為給定fromMap.Entry通過給定 EntryTransformer轉換后的值。

filterKeys(Map<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回給定unfilteredMap中的鍵值通過給定keyPredicate過濾后的map映射。

filterKeys(SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回給定unfilteredMap中的鍵值通過給定keyPredicate過濾后的SortedMap映射。

filterKeys(NavigableMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回給定unfilteredMap中的鍵值通過給定keyPredicate過濾后的NavigableMap映射。

filterKeys(BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate):返回給定unfilteredMap中的鍵值通過給定keyPredicate過濾后的BiMap映射。

filterValues( Map<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回給定unfilteredMap中的value值通過給定keyPredicate過濾后的map映射。

filterValues(SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回給定unfilteredMap中的value值通過給定keyPredicate過濾后的SortedMap映 射。

filterValues(NavigableMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回給定unfilteredMap中的value值通過給定keyPredicate過濾后的 NavigableMap映射。

filterValues(BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate):返回給定unfilteredMap中的value值通過給定keyPredicate過濾后的BiMap映射。

filterEntries( Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回給定unfilteredMap.Entry中的Entry值通過給定entryPredicate過濾后的map 映射。

filterEntries( SortedMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回給定unfilteredMap.Entry中的Entry值通過給定entryPredicate過濾后的 SortedMap映射。

filterEntries( NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回給定unfilteredMap.Entry中的Entry值通過給定entryPredicate過濾后的 NavigableMap映射。

filterEntries( BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate):返回給定unfilteredMap.Entry中的Entry值通過給定entryPredicate過濾后的 BiMap映射。

unmodifiableNavigableMap(NavigableMap<K, V> map):返回給定map的不可修改NavigableMap表示。

synchronizedNavigableMap( NavigableMap<K, V> navigableMap):返回一個同步的(線程安全)的NavigableMap,由給定的navigableMap支持。

Maps類中提供的方法很多,對其中的一些方法也是一知半解,需要慢慢摸索,這里對其中的一些重點和特別的方法做一些示例學習,其他的方法不再贅述,示例代碼如下:

/**
 * Maps:處理Map實例的實用類
 * Maps里面方法很多,一知半解,慢慢摸索
 * User: Realfighter
 * Date: 2014/9/5
 * Time: 15:11
 */
public class MapsTest { @Test public void testMaps() { /** * difference:返回兩個給定map之間的差異。 */ Map<String, String> map1 = new HashMap<String, String>() { { put("a", "1"); } }; Map<String, String> map2 = new HashMap<String, String>() { { put("b", "2"); } }; Map<String, String> map3 = new HashMap<String, String>() { { put("a", "3"); } }; //輸出:not equal: only on left={a=1}: only on right={b=2} System.out.println(Maps.difference(map1, map2)); //輸出:not equal: value differences={a=(1, 3)} System.out.println(Maps.difference(map1, map3)); /** * asMap:返回一個活動的map * 鍵值為給定的set中的值 * value為通過給定Function計算后的值。 */ Set<String> set = Sets.newHashSet("a", "b", "c"); //Function:簡單的對元素做大寫轉換,下面示例多次使用 Function<String, String> function = new Function<String, String>() { @Override public String apply(String input) { return input.toUpperCase(); } }; //輸出:{b=B, c=C, a=A} System.out.println(Maps.asMap(set, function)); /** * toMap:返回一個不可變的ImmutableMap實例 * 其鍵值為給定keys中去除重復值后的值 * 其值為鍵被計算了valueFunction后的值 */ List<String> keys = Lists.newArrayList("a", "b", "c", "a"); //輸出:{a=A, b=B, c=C} System.out.println(Maps.toMap(keys, function)); /** * uniqueIndex:返回一個不可變的ImmutableMap實例, * 其value值為按照給定順序的給定的values值 * 鍵值為相應的值經過給定Function計算后的值 */ List<String> values = Lists.newArrayList("a", "b", "c", "d"); /** * 注:這里的value值不可重復,重復的話在轉換后會拋出異常: * IllegalArgumentException: Multiple entries with same key */ //輸出:{A=a, B=b, C=c, D=d} System.out.println(Maps.uniqueIndex(values, function)); /** * transformValues:返回一個map映射 * 其鍵值為給定fromMap的鍵值 * 其value為給定formMap中value通過Function轉換后的值 */ Map<String, Boolean> fromMap = Maps.newHashMap(); fromMap.put("key", true); fromMap.put("value", false); //輸出:{value=true, key=false} System.out.println(Maps.transformValues(fromMap, new Function<Boolean, Object>() { @Override public Object apply(Boolean input) { //對傳入的元素取反 return !input; } })); /** * transformEntries:返回一個map映射 * 其Entry為給定fromMap.Entry通過給定EntryTransformer轉換后的值 */ Maps.EntryTransformer<String, Boolean, String> entryTransformer = new Maps.EntryTransformer<String, Boolean, String>() { public String transformEntry(String key, Boolean value) { //value為假,則key變大寫 return value ? key : key.toUpperCase(); } }; //輸出:{value=VALUE, key=key} System.out.println(Maps.transformEntries(fromMap, entryTransformer)); /** * filterKeys:返回給定unfilteredMap中的鍵值通過給定keyPredicate過濾后的map映射 */ //輸出:{key=true} System.out.println(Maps.filterKeys(fromMap, new Predicate<String>() { @Override public boolean apply(String input) { //過濾Map中鍵值包含字母y的元素 return input.contains("y"); } })); /** * filterValues:返回給定unfilteredMap中的value值通過給定keyPredicate過濾后的map映射 */ //輸出:{value=false} System.out.println(Maps.filterValues(fromMap, new Predicate<Boolean>() { @Override public boolean apply(Boolean input) { //過濾Map中value值為假的元素 return !input; } })); /** * filterEntries:返回給定unfilteredMap.Entry中的Entry值通過給定entryPredicate過濾后的map映射 */ //輸出:{key=true} System.out.println(Maps.filterEntries(fromMap, new Predicate<Map.Entry<String, Boolean>>() { @Override public boolean apply(Map.Entry<String, Boolean> input) { //過濾Map.Entry中getValue()為真的元素 return input.getValue(); } })); } }

Multimaps:
想 Map<String, List<StudentScore>> StudentScoreMap = new HashMap<String, List<StudentScore>>()這樣的數據結構,自己實現起來太麻煩,你需要檢查key是否存在,
不存在時則創建一個,存在時在List后面添加上一個。這個過程是比較痛苦的,如果你希望檢查List中的對象是否存在,刪除一個對象,或者遍歷整個數據結構,那么則需要更多的代碼來實現。
import java.util.Collection;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;

public class MutliMapTest { public static void main(String... args) { Multimap<String, String> myMultimap = ArrayListMultimap.create(); // Adding some key/value myMultimap.put("Fruits", "Bannana"); myMultimap.put("Fruits", "Apple"); myMultimap.put("Fruits", "Pear"); myMultimap.put("Fruits", "Pear"); myMultimap.put("Vegetables", "Carrot"); // Getting the size int size = myMultimap.size(); System.out.println(size); // 5 // Getting values Collection<String> fruits = myMultimap.get("Fruits"); System.out.println(fruits); // [Bannana, Apple, Pear, Pear] System.out.println(ImmutableSet.copyOf(fruits));// [Bannana, Apple, Pear] // Set<Foo> set = Sets.newHashSet(list); // Set<Foo> foo = new HashSet<Foo>(myList); Collection<String> vegetables = myMultimap.get("Vegetables"); System.out.println(vegetables); // [Carrot] // Iterating over entire Mutlimap for (String value : myMultimap.values()) { System.out.println(value); } // Removing a single value myMultimap.remove("Fruits", "Pear"); System.out.println(myMultimap.get("Fruits")); // [Bannana, Apple, Pear] // Remove all values for a key myMultimap.removeAll("Fruits"); System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!) } }

如果你需要基於multimap直接操作list或者set,那么可以使用在定義類型的時候使用子類名稱:ListMultimap,SetMultimap和SortedSetMultimap。例如:

ListMutlimap<String,String> myMutlimap = ArrayListMultimap.create();

List<string> myValues = myMutlimap.get("myKey"); // Returns a List, not a Collection.

BiMap:
BiMap提供了一種新的集合類型,它提供了key和value的雙向關聯的數據結構。
通常情況下,我們在使用Java的Map時,往往是通過key來查找value的,但是如果出現下面一種場景的情況,我們就需要額外編寫一些代碼了:value查key。

     BiMap<Integer,String> logfileMap = HashBiMap.create(); 
        logfileMap.put(1,"a.log");
        logfileMap.put(2,"b.log");
        logfileMap.put(3,"c.log"); 
        System.out.println("logfileMap:"+logfileMap); 
        BiMap<String,Integer> filelogMap = logfileMap.inverse();
        System.out.println("filelogMap:"+filelogMap);

在使用BiMap時,會要求Value的唯一性。如果value重復了則會拋出錯誤:java.lang.IllegalArgumentException。
如果我們確實需要插入重復的value值,那可以選擇forcePut方法。但是我們需要注意的是前面的key也會被覆蓋了。
inverse方法會返回一個反轉的BiMap,但是注意這個反轉的map不是新的map對象,它實現了一種視圖關聯,這樣你對於反轉后的map的所有操作都會影響原先的map對象。
 
Multiset:
Multiset是什么?顧名思義,Multiset和Set的區別就是可以保存多個相同的對象。在JDK中,List和Set有一個基本的區別,就是List可以包含多個相同對象,且是有順序的,而Set不能有重復,且不保證順序(有些實現有順序,例如LinkedHashSet和SortedSet等)所以Multiset占據了List和Set之間的一個灰色地帶:允許重復,但是不保證順序。 
常見使用場景:Multiset有一個有用的功能,就是跟蹤每種對象的數量,所以你可以用來進行數字統計。實現方式如下:

String strWorld="wer|dfd|dd|dfd|dda|de|dr";
        String[] words=strWorld.split("\\|");
        List<String> wordList=new ArrayList<String>();
        for (String word : words) {
            wordList.add(word);
        }
        Multiset<String> wordsMultiset = HashMultiset.create();
        wordsMultiset.addAll(wordList);
for(String key:wordsMultiset.elementSet()){ System.out.println(key+" count:"+wordsMultiset.count(key)); }
上面的代碼實現的功能非常簡單,用於記錄字符串在數組中出現的次數。這種場景在實際的開發過程還是容易經常出現的。

Multiset主要方法

  Multiset接口定義的接口主要有:
    add(E element) :向其中添加單個元素
    add(E element,int occurrences) : 向其中添加指定個數的元素
    count(Object element) : 返回給定參數元素的個數
    remove(E element) : 移除一個元素,其count值 會響應減少
    remove(E element,int occurrences): 移除相應個數的元素
    elementSet() : 將不同的元素放入一個Set中
    entrySet(): 類似與Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
    setCount(E element ,int count): 設定某一個元素的重復次數
    setCount(E element,int oldCount,int newCount): 將符合原有重復個數的元素修改為新的重復次數
    retainAll(Collection c) : 保留出現在給定集合參數的所有的元素 
    removeAll(Collectionc) : 去除出現給給定集合參數的所有的元素

 

public void testMultsetWordCount(){
        String strWorld="wer|dfd|dd|dfd|dda|de|dr";
        String[] words=strWorld.split("\\|");
        List<String> wordList=new ArrayList<String>();
        for (String word : words) {
            wordList.add(word);
        }
        Multiset<String> wordsMultiset = HashMultiset.create();
        wordsMultiset.addAll(wordList);
        
        
        //System.out.println("wordsMultiset:"+wordsMultiset);
        
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
        
        if(!wordsMultiset.contains("peida")){
            wordsMultiset.add("peida", 2);
        }
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
        
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 23,45);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
        
        if(wordsMultiset.contains("peida")){
            wordsMultiset.setCount("peida", 44,67);
        }
        
        System.out.println("============================================");
        for(String key:wordsMultiset.elementSet()){
            System.out.println(key+" count:"+wordsMultiset.count(key));
        }
    }

輸出:
de count:1
dda count:1
dd count:1
dfd count:2
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:2
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:23
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:45
wer count:1
dr count:1
============================================
de count:1
dda count:1
dd count:1
dfd count:2
peida count:45
wer count:1
dr count:1

說明:setCount(E element,int oldCount,int newCount): 方法,如果傳入的oldCount和element的不一致的時候,是不能講element的count設置成newCount的。需要注意。

Multiset不是Map

  需要注意的是Multiset不是一個Map<E,Integer>,盡管Multiset提供一部分類似的功能實現。其它值得關注的差別有:
  Multiset中的元素的重復個數只會是正數,且最大不會超過Integer.MAX_VALUE。設定計數為0的元素將不會出現multiset中,也不會出現elementSet()和entrySet()的返回結果中。
  multiset.size() 方法返回的是所有的元素的總和,相當於是將所有重復的個數相加。如果需要知道每個元素的個數可以使用elementSet().size()得到.(因而調用add(E)方法會是multiset.size()增加1).
  multiset.iterator() 會循環迭代每一個出現的元素,迭代的次數與multiset.size()相同。 iterates over each occurrence of each element, so the length of the iteration is equal to multiset.size().
  Multiset 支持添加、移除多個元素以及重新設定元素的個數。執行setCount(element,0)相當於移除multiset中所有的相同元素。
  調用multiset.count(elem)方法時,如果該元素不在該集中,那么返回的結果只會是0。

 

 

 

 

 

 

 

 






 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM