文章引用:http://ifeve.com/google-guava-immutablecollections/
一灵临、 不可變集合
為什么要使用不可變集合
-
優(yōu)點(diǎn):
- 當(dāng)對象被不可信的庫調(diào)用時,不可變形式是安全的赫蛇;
- 不可變對象被多個線程調(diào)用時返吻,不存在競態(tài)條件問題挫剑;
- 不可變集合不需要考慮變化,因此可以節(jié)省時間和空間藤为。所有不可變的集合都比它們的可變形式有更好的內(nèi)存利用率;
- 不可變對象因?yàn)橛泄潭ú蛔兌嵝蹋梢宰鳛槌A縼戆踩褂谩?/li>
不可變集合的幾種創(chuàng)建方式:
copyOf方法
List<String> list = Arrays.asList("a", "b", "c");
ImmutableSet<String> strings = ImmutableSet.copyOf(list);
of方法
ImmutableSet<String> of = ImmutableSet.of("a", "b", "c", "d", "e");
Builder工具
ImmutableSet<String> set = ImmutableSet.<String>builder().add("a").add("b").add("c").build();
二缅疟、 新的集合類型
可變集合與不可變集合(來自并發(fā)編程網(wǎng)).png
1.Multiset
Multiset<String> multiset = HashMultiset.create();
multiset.add("a");
multiset.add("a");
multiset.add("b");
int a = multiset.count("a");
System.out.println("包含重復(fù)元素的個數(shù) " + multiset.size());
System.out.println("不包含重復(fù)元素的個數(shù) " + multiset.elementSet().size());
// 可以統(tǒng)計每個元素出現(xiàn)的個數(shù)
System.out.println("元素a出現(xiàn)的次數(shù) " + a);
----------------------------------
out:
包含重復(fù)元素的個數(shù) 3
不包含重復(fù)元素的個數(shù) 2
元素a出現(xiàn)的次數(shù) 2
Guava 提供了多種Multiset實(shí)現(xiàn)
Multiset的多種實(shí)現(xiàn).png
SortedMultiset
SortedMultiset是Multiset 接口的變種,它支持高效地獲取指定范圍的子集遍愿。
eg:
SortedMultiset<String> sortedMultiset = TreeMultiset.create();
sortedMultiset.add("a");
sortedMultiset.add("b");
sortedMultiset.add("c");
sortedMultiset.add("d");
sortedMultiset.add("e");
SortedMultiset<String> strings = sortedMultiset.subMultiset("a", BoundType.CLOSED, "e", BoundType.OPEN);
strings.forEach(System.out::print);
----------------------------------
out:
輸出:abcd
2.Multimap
ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("a", 1);
multimap.put("a", 2);
multimap.put("a", 3);
multimap.put("a", 4);
multimap.put("b", 1);
System.out.println(multimap.size());
// asMap() 提供Map<K,Collection<V>>形式的視圖 collections 中
// a->{1,2,3,4}
// b->{1}
Collection<Collection<Integer>> collections = multimap.asMap().values();
// values {1,2,3,4,1}
Collection<Integer> values = multimap.values();
Collection<Map.Entry<String, Integer>> entries = multimap.entries();
entries.forEach(item -> {
System.out.print("key--->" + item.getKey());
System.out.println(" value--->" + item.getValue());
});
----------------------------------
out:
5
key--->a value--->1
key--->a value--->2
key--->a value--->3
key--->a value--->4
key--->b value--->1
Multimap的各種實(shí)現(xiàn)
Multimap的各種實(shí)現(xiàn).png
3.RangeSet
RangeSet<Integer> rangeSet = TreeRangeSet.create();
// 閉區(qū)間 [1,10]
rangeSet.add(Range.closed(1, 10));
// 左閉右開區(qū)間 [11,15) 如果左邊為11 則和上邊的區(qū)間為不連續(xù)區(qū)間 如果左邊為10 則兩個區(qū)間進(jìn)行合并
rangeSet.add(Range.closedOpen(11, 15));
// 返回包含指定元素的區(qū)間存淫,如果沒有這樣的區(qū)間則返回null
Range<Integer> integerRange = rangeSet.rangeContaining(5);
// 返回包含rangeSet 所有區(qū)間的最小區(qū)間
Range<Integer> span = rangeSet.span();
System.out.println(integerRange);
System.out.println(span);
---------------------------------
out:
[1..10]
[1..15)
還存在一個RangeMap<Integer, String> ,但是和RangeSet不同的是RangeMap不會合并相鄰的映射沼填,即便相鄰的區(qū)間映射到相同的值桅咆。
4.Table
Table<String, Integer, String> table = HashBasedTable.create();
table.put("a", 1, "第一個值");
table.put("a", 2, "第二個值");
table.put("a", 3, "第三個值");
table.put("b", 1, "第一個值");
table.put("b", 4, "第四個值");
Map<Integer, String> a = table.row("a");
Map<Integer, String> b = table.row("b");
Map<String, String> column = table.column(1);
Set<Table.Cell<String, Integer, String>> cells = table.cellSet();
Map<Integer, Map<String, String>> columnMap = table.columnMap();
Collection<String> values = table.values();
System.out.println("");
Table:output
Table的多種實(shí)現(xiàn)
Table的多種實(shí)現(xiàn).png