日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具

發布時間:2024/4/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接?譯文鏈接?譯者:沈義揚,校對:丁一

尚未完成: Queues, Tables工具類

任何對JDK集合框架有經驗的程序員都熟悉和喜歡java.util.Collections包含的工具方法。Guava沿著這些路線提供了更多的工具方法:適用于所有集合的靜態方法。這是Guava最流行和成熟的部分之一。

我們用相對直觀的方式把工具類與特定集合接口的對應關系歸納如下:

集合接口屬于JDK還是Guava對應的Guava工具類
CollectionJDKCollections2:不要和java.util.Collections混淆
ListJDKLists
SetJDKSets
SortedSetJDKSets
MapJDKMaps
SortedMapJDKMaps
QueueJDKQueues
MultisetGuavaMultisets
MultimapGuavaMultimaps
BiMapGuavaMaps
TableGuavaTables

在找類似轉化、過濾的方法?請看第四章,函數式風格。

靜態工廠方法

在JDK 7之前,構造新的范型集合時要討厭地重復聲明范型:

1List<TypeThatsTooLongForItsOwnGood> list =?new?ArrayList<TypeThatsTooLongForItsOwnGood>();

我想我們都認為這很討厭。因此Guava提供了能夠推斷范型的靜態工廠方法:

1List<TypeThatsTooLongForItsOwnGood> list = Lists.newArrayList();
2Map<KeyType, LongishValueType> map = Maps.newLinkedHashMap();

可以肯定的是,JDK7版本的鉆石操作符(<>)沒有這樣的麻煩:

1List<TypeThatsTooLongForItsOwnGood> list =?new?ArrayList<>();

但Guava的靜態工廠方法遠不止這么簡單。用工廠方法模式,我們可以方便地在初始化時就指定起始元素。

1Set<Type> copySet = Sets.newHashSet(elements);
2List<String> theseElements = Lists.newArrayList("alpha",?"beta",?"gamma");

此外,通過為工廠方法命名(Effective Java第一條),我們可以提高集合初始化大小的可讀性:

1List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
2List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
3Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);

確切的靜態工廠方法和相應的工具類一起羅列在下面的章節。

注意:Guava引入的新集合類型沒有暴露原始構造器,也沒有在工具類中提供初始化方法。而是直接在集合類中提供了靜態工廠方法,例如:

1Multiset<String> multiset = HashMultiset.create();

Iterables

在可能的情況下,Guava提供的工具方法更偏向于接受Iterable而不是Collection類型。在Google,對于不存放在主存的集合——比如從數據庫或其他數據中心收集的結果集,因為實際上還沒有攫取全部數據,這類結果集都不能支持類似size()的操作 ——通常都不會用Collection類型來表示。

因此,很多你期望的支持所有集合的操作都在Iterables類中。大多數Iterables方法有一個在Iterators類中的對應版本,用來處理Iterator。

截至Guava 1.2版本,Iterables使用FluentIterable類進行了補充,它包裝了一個Iterable實例,并對許多操作提供了”fluent”(鏈式調用)語法。

下面列出了一些最常用的工具方法,但更多Iterables的函數式方法將在第四章討論。

常規方法

concat(Iterable<Iterable>)串聯多個iterables的懶視圖*concat(Iterable...)
frequency(Iterable, Object)返回對象在iterable中出現的次數與Collections.frequency (Collection, ? Object)比較;Multiset
partition(Iterable, int)把iterable按指定大小分割,得到的子集都不能進行修改操作Lists.partition(List, int);paddedPartition(Iterable, int)
getFirst(Iterable, T default)返回iterable的第一個元素,若iterable為空則返回默認值與Iterable.iterator(). next()比較;FluentIterable.first()
getLast(Iterable)返回iterable的最后一個元素,若iterable為空則拋出NoSuchElementExceptiongetLast(Iterable, T default);
FluentIterable.last()
elementsEqual(Iterable, Iterable)如果兩個iterable中的所有元素相等且順序一致,返回true與List.equals(Object)比較
unmodifiableIterable(Iterable)返回iterable的不可變視圖與Collections. unmodifiableCollection(Collection)比較
limit(Iterable, int)限制iterable的元素個數限制給定值FluentIterable.limit(int)
getOnlyElement(Iterable)獲取iterable中唯一的元素,如果iterable為空或有多個元素,則快速失敗getOnlyElement(Iterable, T default)

*譯者注:懶視圖意味著如果還沒訪問到某個iterable中的元素,則不會對它進行串聯操作。

1Iterable<Integer> concatenated = Iterables.concat(
2????????Ints.asList(1,?2,?3),
3????????Ints.asList(4,?5,?6));?// concatenated包括元素 1, 2, 3, 4, 5, 6
4String lastAdded = Iterables.getLast(myLinkedHashSet);
5String theElement = Iterables.getOnlyElement(thisSetIsDefinitelyASingleton);
6//如果set不是單元素集,就會出錯了!

與Collection方法相似的工具方法

通常來說,Collection的實現天然支持操作其他Collection,但卻不能操作Iterable。

下面的方法中,如果傳入的Iterable是一個Collection實例,則實際操作將會委托給相應的Collection接口方法。例如,往Iterables.size方法傳入是一個Collection實例,它不會真的遍歷iterator獲取大小,而是直接調用Collection.size。

方法類似的Collection方法等價的FluentIterable方法
addAll(Collection addTo, ? Iterable toAdd)Collection.addAll(Collection)?
contains(Iterable, Object)Collection.contains(Object)FluentIterable.contains(Object)
removeAll(Iterable ? removeFrom, Collection toRemove)Collection.removeAll(Collection)?
retainAll(Iterable ? removeFrom, Collection toRetain)Collection.retainAll(Collection)?
size(Iterable)Collection.size()FluentIterable.size()
toArray(Iterable, Class)Collection.toArray(T[])FluentIterable.toArray(Class)
isEmpty(Iterable)Collection.isEmpty()FluentIterable.isEmpty()
get(Iterable, int)List.get(int)FluentIterable.get(int)
toString(Iterable)Collection.toString()FluentIterable.toString()

FluentIterable

除了上面和第四章提到的方法,FluentIterable還有一些便利方法用來把自己拷貝到不可變集合

ImmutableList?
ImmutableSettoImmutableSet()
ImmutableSortedSettoImmutableSortedSet(Comparator)

Lists

除了靜態工廠方法和函數式編程方法,Lists為List類型的對象提供了若干工具方法。

方法描述
partition(List, int)把List按指定大小分割
reverse(List)返回給定List的反轉視圖。注: 如果List是不可變的,考慮改用ImmutableList.reverse()。
1List countUp = Ints.asList(1,?2,?3,?4,?5);
2List countDown = Lists.reverse(theList);?// {5, 4, 3, 2, 1}
3List<List> parts = Lists.partition(countUp,?2);//{{1,2}, {3,4}, {5}}

靜態工廠方法

Lists提供如下靜態工廠方法:

具體實現類型工廠方法
ArrayListbasic,?with elements,?from?Iterable,?with exact capacity,?with expected size,?from?Iterator
LinkedListbasic,?from?Iterable

Sets

Sets工具類包含了若干好用的方法。

集合理論方法

我們提供了很多標準的集合運算(Set-Theoretic)方法,這些方法接受Set參數并返回SetView,可用于:

  • 直接當作Set使用,因為SetView也實現了Set接口;
  • 用copyInto(Set)拷貝進另一個可變集合;
  • 用immutableCopy()對自己做不可變拷貝。
方法
union(Set, Set)
intersection(Set, Set)
difference(Set, Set)
symmetricDifference(Set, ? Set)

使用范例:

1Set<String> wordsWithPrimeLength = ImmutableSet.of("one",?"two",?"three",?"six",?"seven",?"eight");
2Set<String> primes = ImmutableSet.of("two",?"three",?"five",?"seven");
3SetView<String> intersection = Sets.intersection(primes,wordsWithPrimeLength);
4// intersection包含"two", "three", "seven"
5return?intersection.immutableCopy();//可以使用交集,但不可變拷貝的讀取效率更高

其他Set工具方法

方法描述另請參見
cartesianProduct(List<Set>)返回所有集合的笛卡兒積cartesianProduct(Set...)
powerSet(Set)返回給定集合的所有子集?
1Set<String> animals = ImmutableSet.of("gerbil",?"hamster");
2Set<String> fruits = ImmutableSet.of("apple",?"orange",?"banana");
3?
4Set<List<String>> product = Sets.cartesianProduct(animals, fruits);
5// {{"gerbil", "apple"}, {"gerbil", "orange"}, {"gerbil", "banana"},
6// ?{"hamster", "apple"}, {"hamster", "orange"}, {"hamster", "banana"}}
7?
8Set<Set<String>> animalSets = Sets.powerSet(animals);
9// {{}, {"gerbil"}, {"hamster"}, {"gerbil", "hamster"}}

靜態工廠方法

Sets提供如下靜態工廠方法:

具體實現類型工廠方法
HashSetbasic,?with elements,?from?Iterable,?with expected size,?from?Iterator
LinkedHashSetbasic,?from?Iterable,?with expected size
TreeSetbasic,?with?Comparator,?from?Iterable

Maps

Maps類有若干值得單獨說明的、很酷的方法。

uniqueIndex

Maps.uniqueIndex(Iterable,Function)通常針對的場景是:有一組對象,它們在某個屬性上分別有獨一無二的值,而我們希望能夠按照這個屬性值查找對象——譯者注:這個方法返回一個Map,鍵為Function返回的屬性值,值為Iterable中相應的元素,因此我們可以反復用這個Map進行查找操作。

比方說,我們有一堆字符串,這些字符串的長度都是獨一無二的,而我們希望能夠按照特定長度查找字符串:

1ImmutableMap<Integer, String> stringsByIndex = Maps.uniqueIndex(strings,
2????new?Function<String, Integer> () {
3????????public?Integer apply(String string) {
4????????????return?string.length();
5????????}
6????});

如果索引值不是獨一無二的,請參見下面的Multimaps.index方法。

difference

Maps.difference(Map, Map)用來比較兩個Map以獲取所有不同點。該方法返回MapDifference對象,把不同點的維恩圖分解為:

entriesInCommon()兩個Map中都有的映射項,包括匹配的鍵與值
entriesDiffering()鍵相同但是值不同值映射項。返回的Map的值類型為MapDifference.ValueDifference,以表示左右兩個不同的值
entriesOnlyOnLeft()鍵只存在于左邊Map的映射項
entriesOnlyOnRight()鍵只存在于右邊Map的映射項
1Map<String, Integer> left = ImmutableMap.of("a",?1,?"b",?2,?"c",?3);
2Map<String, Integer> left = ImmutableMap.of("a",?1,?"b",?2,?"c",?3);
3MapDifference<String, Integer> diff = Maps.difference(left, right);
4?
5diff.entriesInCommon();?// {"b" => 2}
6diff.entriesInCommon();?// {"b" => 2}
7diff.entriesOnlyOnLeft();?// {"a" => 1}
8diff.entriesOnlyOnRight();?// {"d" => 5}

處理BiMap的工具方法

Guava中處理BiMap的工具方法在Maps類中,因為BiMap也是一種Map實現。

BiMap工具方法相應的Map工具方法
synchronizedBiMap(BiMap)Collections.synchronizedMap(Map)
unmodifiableBiMap(BiMap)Collections.unmodifiableMap(Map)

靜態工廠方法

Maps提供如下靜態工廠方法:

具體實現類型工廠方法
HashMapbasic,?from?Map,?with expected size
LinkedHashMapbasic,?from?Map
TreeMapbasic,?from?Comparator,?from?SortedMap
EnumMapfrom?Class,?from?Map
ConcurrentMap:支持所有操作basic
IdentityHashMapbasic

Multisets

標準的Collection操作會忽略Multiset重復元素的個數,而只關心元素是否存在于Multiset中,如containsAll方法。為此,Multisets提供了若干方法,以顧及Multiset元素的重復性:

方法說明Collection方法的區別
containsOccurrences(Multiset ? sup, Multiset sub)對任意o,如果sub.count(o)<=super.count(o),返回trueCollection.containsAll忽略個數,而只關心sub的元素是否都在super中
removeOccurrences(Multiset ? removeFrom, Multiset toRemove)對toRemove中的重復元素,僅在removeFrom中刪除相同個數。Collection.removeAll移除所有出現在toRemove的元素
retainOccurrences(Multiset ? removeFrom, Multiset toRetain)修改removeFrom,以保證任意o都符合removeFrom.count(o)<=toRetain.count(o)Collection.retainAll保留所有出現在toRetain的元素
intersection(Multiset, ? Multiset)返回兩個multiset的交集;沒有類似方法
01Multiset<String> multiset1 = HashMultiset.create();
02multiset1.add("a",?2);
03?
04Multiset<String> multiset2 = HashMultiset.create();
05multiset2.add("a",?5);
06?
07multiset1.containsAll(multiset2);?//返回true;因為包含了所有不重復元素,
08//雖然multiset1實際上包含2個"a",而multiset2包含5個"a"
09Multisets.containsOccurrences(multiset1, multiset2);?// returns false
10?
11multiset2.removeOccurrences(multiset1);?// multiset2 現在包含3個"a"
12multiset2.removeAll(multiset1);//multiset2移除所有"a",雖然multiset1只有2個"a"
13multiset2.isEmpty();?// returns true

Multisets中的其他工具方法還包括:

copyHighestCountFirst(Multiset)返回Multiset的不可變拷貝,并將元素按重復出現的次數做降序排列
unmodifiableMultiset(Multiset)返回Multiset的只讀視圖
unmodifiableSortedMultiset(SortedMultiset)返回SortedMultiset的只讀視圖
1Multiset<String> multiset = HashMultiset.create();
2multiset.add("a",?3);
3multiset.add("b",?5);
4multiset.add("c",?1);
5?
6ImmutableMultiset highestCountFirst = Multisets.copyHighestCountFirst(multiset);
7//highestCountFirst,包括它的entrySet和elementSet,按{"b", "a", "c"}排列元素

Multimaps

Multimaps提供了若干值得單獨說明的通用工具方法

index

作為Maps.uniqueIndex的兄弟方法,Multimaps.index(Iterable, Function)通常針對的場景是:有一組對象,它們有共同的特定屬性,我們希望按照這個屬性的值查詢對象,但屬性值不一定是獨一無二的。

比方說,我們想把字符串按長度分組。

01ImmutableSet digits = ImmutableSet.of("zero",?"one",?"two",?"three",?"four",?"five",?"six",?"seven",?"eight",?"nine");
02Function<String, Integer> lengthFunction =?new?Function<String, Integer>() {
03????public?Integer apply(String string) {
04????????return?string.length();
05????}
06};
07?
08ImmutableListMultimap<Integer, String> digitsByLength= Multimaps.index(digits, lengthFunction);
09/*
10* ?digitsByLength maps:
11* ?3 => {"one", "two", "six"}
12* ?4 => {"zero", "four", "five", "nine"}
13* ?5 => {"three", "seven", "eight"}
14*/

invertFrom

鑒于Multimap可以把多個鍵映射到同一個值(譯者注:實際上這是任何map都有的特性),也可以把一個鍵映射到多個值,反轉Multimap也會很有用。Guava 提供了invertFrom(Multimap toInvert,
Multimap dest)做這個操作,并且你可以自由選擇反轉后的Multimap實現。

注:如果你使用的是ImmutableMultimap,考慮改用ImmutableMultimap.inverse()做反轉。

01ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
02multimap.putAll("b", Ints.asList(2,?4,?6));
03multimap.putAll("a", Ints.asList(4,?2,?1));
04multimap.putAll("c", Ints.asList(2,?5,?3));
05?
06TreeMultimap<Integer, String> inverse = Multimaps.invertFrom(multimap, TreeMultimap<String, Integer>.create());
07//注意我們選擇的實現,因為選了TreeMultimap,得到的反轉結果是有序的
08/*
09* inverse maps:
10* ?1 => {"a"}
11* ?2 => {"a", "b", "c"}
12* ?3 => {"c"}
13* ?4 => {"a", "b"}
14* ?5 => {"c"}
15* ?6 => {"b"}
16*/

forMap

想在Map對象上使用Multimap的方法嗎?forMap(Map)把Map包裝成SetMultimap。這個方法特別有用,例如,與Multimaps.invertFrom結合使用,可以把多對一的Map反轉為一對多的Multimap。

1Map<String, Integer> map = ImmutableMap.of("a",?1,?"b",?1,?"c",?2);
2SetMultimap<String, Integer> multimap = Multimaps.forMap(map);
3// multimap:["a" => {1}, "b" => {1}, "c" => {2}]
4Multimap<Integer, String> inverse = Multimaps.invertFrom(multimap, HashMultimap<Integer, String>.create());
5// inverse:[1 => {"a","b"}, 2 => {"c"}]

包裝器

Multimaps提供了傳統的包裝方法,以及讓你選擇Map和Collection類型以自定義Multimap實現的工具方法。

只讀包裝MultimapListMultimapSetMultimapSortedSetMultimap
同步包裝MultimapListMultimapSetMultimapSortedSetMultimap
自定義實現MultimapListMultimapSetMultimapSortedSetMultimap

自定義Multimap的方法允許你指定Multimap中的特定實現。但要注意的是:

  • Multimap假設對Map和Supplier產生的集合對象有完全所有權。這些自定義對象應避免手動更新,并且在提供給Multimap時應該是空的,此外還不應該使用軟引用、弱引用或虛引用。
  • 無法保證修改了Multimap以后,底層Map的內容是什么樣的。
  • 即使Map和Supplier產生的集合都是線程安全的,它們組成的Multimap也不能保證并發操作的線程安全性。并發讀操作是工作正常的,但需要保證并發讀寫的話,請考慮用同步包裝器解決。
  • 只有當Map、Supplier、Supplier產生的集合對象、以及Multimap存放的鍵值類型都是可序列化的,Multimap才是可序列化的。
  • Multimap.get(key)返回的集合對象和Supplier返回的集合對象并不是同一類型。但如果Supplier返回的是隨機訪問集合,那么Multimap.get(key)返回的集合也是可隨機訪問的。

請注意,用來自定義Multimap的方法需要一個Supplier參數,以創建嶄新的集合。下面有個實現ListMultimap的例子——用TreeMap做映射,而每個鍵對應的多個值用LinkedList存儲。

1ListMultimap<String, Integer> myMultimap = Multimaps.newListMultimap(
2????Maps.<String, Collection>newTreeMap(),
3????new?Supplier<LinkedList>() {
4????????public?LinkedList get() {
5????????????return?Lists.newLinkedList();
6????????}
7????});

Tables

Tables類提供了若干稱手的工具方法。

自定義Table

堪比Multimaps.newXXXMultimap(Map, Supplier)工具方法,Tables.newCustomTable(Map, Supplier<Map>)允許你指定Table用什么樣的map實現行和列。

1// 使用LinkedHashMaps替代HashMaps
2Table<String, Character, Integer> table = Tables.newCustomTable(
3Maps.<String, Map<Character, Integer>>newLinkedHashMap(),
4new?Supplier<Map<Character, Integer>> () {
5public?Map<Character, Integer> get() {
6return?Maps.newLinkedHashMap();
7}
8});

transpose

transpose(Table<R, C, V>)方法允許你把Table<C, R, V>轉置成Table<R, C, V>。例如,如果你在用Table構建加權有向圖,這個方法就可以把有向圖反轉。

包裝器

還有很多你熟悉和喜歡的Table包裝類。然而,在大多數情況下還請使用ImmutableTable

UnmodifiableTableRowSortedTable

原創文章,轉載請注明:?轉載自并發編程網 – ifeve.com本文鏈接地址:?[Google Guava] 2.3-強大的集合工具類:java.util.Collections中未包含的集合工具

轉載于:https://www.cnblogs.com/Luwak90/p/9850575.html

總結

以上是生活随笔為你收集整理的[Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。