Google Guava API学习笔记(2):集合

[b][size=x-large]不可变集合 Immutable Collections[/size][/b]


[b][size=large]例子[/size][/b]
public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
"red",
"orange",
"yellow",
"green",
"blue",
"purple");

class Foo {
Set<Bar> bars;
Foo(Set<Bar> bars) {
this.bars = ImmutableSet.copyOf(bars); // defensive copy!
}
}


[b][size=large]为啥?[/size][/b]

不可变对象拥有众多好处:

[list]
[*]Safe for use by untrusted libraries.
[*]Thread-safe: can be used by many threads with no risk of race conditions.
[*]Doesn't need to support mutation, and can make time and space savings with that assumption. All immutable collection implementations are more memory-efficient than their mutable siblings (analysis)
[*]Can be used as a constant, with the expectation that it will remain fixed
[/list]

防止可变对象拷贝是一个良好的编程习惯,请看这儿:[url]http://www.javapractices.com/topic/TopicAction.do?Id=15[/url]

Making immutable copies of objects is a good defensive programming technique. Guava provides simple, easy-to-use immutable versions of each standard Collection type, including Guava's own Collection variations.

接下来,Guava说居然JDK的Colletions提供了一套Collections.unmodifiableXXX方法,但不太好用,因此Guava不是在重复造轮子。又强调说,如果你不希望对一个集合进行update,那么最好采用防御性拷贝方式,将它们拷贝到一个不可变的集合中。Guava的集合实现都不支持null的元素(Guva通过研究,发现95%的情况不需要使用null的集合元素),所以如果需要null集合元素,就不能用Guava了。

[b][size=large]咋整?[/size][/b]

可使用如下方法创建不可变集合:
[list]
[*]using the copyOf method, for example, ImmutableSet.copyOf(set)
[*]using the of method, for example, ImmutableSet.of("a", "b", "c") or ImmutableMap.of("a", 1, "b", 2)
[*]using a Builder, 看示例:
[/list]


public static final ImmutableSet<Color> GOOGLE_COLORS =
ImmutableSet.<Color>builder()
.addAll(WEBSAFE_COLORS)
.add(new Color(0, 191, 255))
.build();



[b]使用copeOf(0[/b]


ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");
thingamajig(foobar);

void thingamajig(Collection<String> collection) {
ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection);
...
}


[b]asList[/b]

All immutable collections provide an ImmutableList view via asList(), so -- for example -- even if you have data stored as an ImmutableSortedSet, you can get the kth smallest element with sortedSet.asList().get(k).

通过asList构造的List通常比直接new ArrayList要快,毕竟它是指定大小的。


[b][size=large]在哪?[/size][/b]

[table]
|Interface| JDK or Guava?| Immutable Version|
|Collection| JDK|ImmutableCollection|
|List| JDK|ImmutableList|
|Set| JDK|ImmutableSet|
|SortedSet/NavigableSet| JDK|ImmutableSortedSet|
|Map| JDK|ImmutableMap|
|SortedMap| JDK|ImmutableSortedMap|
|Multiset| Guava|ImmutableMultiset|
|SortedMultiset| Guava|ImmutableSortedMultiset|
|Multimap| Guava|ImmutableMultimap|
|ListMultimap| Guava|ImmutableListMultimap|
|SetMultimap| Guava|ImmutableSetMultimap|
|BiMap| Guava|ImmutableBiMap|
|ClassToInstanceMap| Guava|ImmutableClassToInstanceMap|
|Table| Guava|ImmutableTable
[/table]

[b][size=x-large]创建集合[/size][/b]

[b][size=large]简化集合创建[/size][/b]
原来多麻烦:

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<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);


[b][size=large]Table[/size][/b]

Table<Vertex, Vertex, Double> weightedGraph = HashBasedTable.create();
weightedGraph.put(v1, v2, 4);
weightedGraph.put(v1, v3, 20);
weightedGraph.put(v2, v3, 5);

weightedGraph.row(v1); // returns a Map mapping v2 to 4, v3 to 20
weightedGraph.column(v3); // returns a Map mapping v1 to 20, v2 to 5


[b][size=x-large]工具类[/size][/b]

[table]
|Interface| JDK or Guava?| Corresponding Guava utility class|
|Collection| JDK|Collections2 (avoiding conflict with java.util.Collections)|
|List| JDK|Lists|
|Set| JDK|Sets|
|SortedSet| JDK|Sets|
|Map| JDK|Maps|
|SortedMap| JDK|Maps|
|Queue| JDK|Queues|
|Multiset| Guava|Multisets|
|Multimap| Guava|Multimaps|
|BiMap| Guava|Maps|
|Table| Guava|Tables
[/table]

JDK 7.0之前:
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<TypeThatsTooLongForItsOwnGood>();


Guava提供如下方式:

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


JDK 7.0才支持:
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<>();



Guava提供更多:

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


指定大小:

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


类似的:
Multiset<String> multiset = HashMultiset.create();


对象工具类提供的方法,如:


List<Integer> countUp = Ints.asList(1, 2, 3, 4, 5);
List<Integer> countDown = Lists.reverse(theList); // {5, 4, 3, 2, 1}

List<List<Integer>> parts = Lists.partition(countUp, 2); // {{1, 2}, {3, 4}, {5}}



不可变工具类提供的方法,如:

Set<String> wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight");
Set<String> primes = ImmutableSet.of("two", "three", "five", "seven");

SetView<String> intersection = Sets.intersection(primes, wordsWithPrimeLength); // contains "two", "three", "seven"
// I can use intersection as a Set directly, but copying it can be more efficient if I use it a lot.
return intersection.immutableCopy();



[b][size=x-large]扩展工具类[/size][/b]

略了,看:[url]http://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值