一、Maps
Maps有许多很酷的实用程序,值得单独解释。
1、uniqueIndex
Maps.uniqueIndex(Iterable,Function)解决了一个常见的情况,即有一堆对象,每个对象都有一些唯一的属性,并希望能够根据该属性查找这些对象。
假设我们有一堆字符串,我们知道它们有唯一的长度,我们希望能够查找具有特定长度的字符串。
ImmutableMap<Integer, String> stringsByIndex = Maps.uniqueIndex(strings, new Function<String, Integer> () {
public Integer apply(String string) {
return string.length();
}
});
如果索引不是唯一的,请参阅下面的Multimaps.index。
2、difference
Maps.difference(Map,Map)允许您比较两张地图之间的所有差异。它返回一个MapDifference对象,该对象将Venn图分解为:
|--------------------------|--------------------------------------------------------------------------|
| Method | Description |
| entriesInCommon() | The entries which are in both maps, with both matching keys and values. |
| entriesDiffering() | 具有相同键但不同值的条目。此映射中的值属于MapDifference.ValueDifference类型,可以查看左右值。 |
| entriesOnlyOnLeft() | Returns the entries whose keys are in the left but not in the right map. |
| entriesOnlyOnRight() | Returns the entries whose keys are in the right but not in the left map. |
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Map<String, Integer> right = ImmutableMap.of("b", 2, "c", 4, "d", 5);
MapDifference<String, Integer> diff = Maps.difference(left, right);
diff.entriesInCommon(); // {"b" => 2}
diff.entriesDiffering(); // {"c" => (3, 4)}
diff.entriesOnlyOnLeft(); // {"a" => 1}
diff.entriesOnlyOnRight(); // {"d" => 5}
3、BiMap
BiMap上的Guava实用程序位于Maps类中,因为BiMap也是Map。
|--------------------------|----------------------------------|
| BiMap utility | Corresponding Map utility |
| synchronizedBiMap(BiMap) | Collections.synchronizedMap(Map) |
| unmodifiableBiMap(BiMap) | Collections.unmodifiableMap(Map) |
4、Static Factories
映射提供以下静态工厂方法。
|--------------------|----------------------------------------|
| Implementation | Factories |
| HashMap | basic, from Map, with expected size |
| LinkedHashMap | basic, from Map |
| TreeMap | basic, from Comparator, from SortedMap |
| EnumMap | from Class, from Map |
| ConcurrentMap | basic |
| IdentityHashMap | basic |
二、Multisets
标准集合操作(如containsAll)忽略多集合中元素的计数,只关心元素是否在多集合中。多集提供了许多考虑多集中元素多重性的操作。
|-----------------------------------------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------|
| Method | Explanation | Difference from Collection method |
| containsOccurrences(Multiset sup, Multiset sub) | Returns true if sub.count(o) <= super.count(o) for all o. | Collection.containsAll忽略计数,只测试是否包含元素。 |
| removeOccurrences(Multiset removeFrom, Multiset toRemove) | Removes one occurrence in removeFrom for each occurrence of an element in toRemove. | Collection.removeAll将删除在to Remove中出现一次的任何元素的所有实例。 |
| retainOccurrences(Multiset removeFrom, Multiset toRetain) | Guarantees that removeFrom.count(o) <= toRetain.count(o) for all o. | Collection.retail将所有出现的元素保留为Retain。 |
| intersection(Multiset, Multiset) | 返回两个多集的交集的视图;一种非破坏性的替代方案。 | Has no analogue. |
Multiset<String> multiset1 = HashMultiset.create();
multiset1.add("a", 2);
Multiset<String> multiset2 = HashMultiset.create();
multiset2.add("a", 5);
multiset1.containsAll(multiset2); // returns true: all unique elements are contained,
// even though multiset1.count("a") == 2 < multiset2.count("a") == 5
Multisets.containsOccurrences(multiset1, multiset2); // returns false
Multisets.removeOccurrences(multiset2, multiset1); // multiset2 now contains 3 occurrences of "a"
multiset2.removeAll(multiset1); // removes all occurrences of "a" from multiset2, even though multiset1.count("a") == 2
multiset2.isEmpty(); // returns true
Multiset中的其他实用程序包括:
|--------------------------------------------|------------------------------------------------------|
| Method | Description |
| copyHighestCountFirst(Multiset) | 返回multiset的不可变副本,该副本按频率降序迭代元素。 |
| unmodifiableMultiset(Multiset) | Returns an unmodifiable view of the multiset. |
| unmodifiableSortedMultiset(SortedMultiset) | Returns an unmodifiable view of the sorted multiset. |
Multiset<String> multiset = HashMultiset.create();
multiset.add("a", 3);
multiset.add("b", 5);
multiset.add("c", 1);
ImmutableMultiset<String> highestCountFirst = Multisets.copyHighestCountFirst(multiset);
// highestCountFirst, like its entrySet and elementSet, iterates over the elements in order {"b", "a", "c"}
三、Multimaps
Multimaps提供了许多通用的实用程序操作,值得单独解释。
1、index
Maps.uniqueIndex,Multimaps.index(Iterable,Function)的表亲回答了这样一种情况,即当您希望能够查找具有某些特定共同属性的所有对象时,这些属性不一定是唯一的。
假设我们希望根据字符串的长度对其进行分组。
ImmutableSet<String> digits = ImmutableSet.of(
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine");
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
};
ImmutableListMultimap<Integer, String> digitsByLength = Multimaps.index(digits, lengthFunction);
/*
* digitsByLength maps:
* 3 => {"one", "two", "six"}
* 4 => {"zero", "four", "five", "nine"}
* 5 => {"three", "seven", "eight"}
*/
2、invertFrom
由于多映射可以将多个关键点映射到一个值,也可以将一个关键点映像到多个值,因此反转多映射非常有用。Guava提供inverteFrom(Multimap to Invert,Multimap dest),让您无需选择实现即可完成此操作。
注意:如果您使用的是ImmutableMultimap,请考虑使用ImmutableMultimap.inverse()。
ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.putAll("b", Ints.asList(2, 4, 6));
multimap.putAll("a", Ints.asList(4, 2, 1));
multimap.putAll("c", Ints.asList(2, 5, 3));
TreeMultimap<Integer, String> inverse = Multimaps.invertFrom(multimap, TreeMultimap.<Integer, String>create());
// note that we choose the implementation, so if we use a TreeMultimap, we get results in order
/*
* inverse maps:
* 1 => {"a"}
* 2 => {"a", "b", "c"}
* 3 => {"c"}
* 4 => {"a", "b"}
* 5 => {"c"}
* 6 => {"b"}
*/
3、forMap
需要在地图上使用Multimap方法吗?forMap(Map)将Map视为SetMultimap。例如,与Multimaps.inverteFrom组合使用时,这一功能特别有用。
Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 1, "c", 2);
SetMultimap<String, Integer> multimap = Multimaps.forMap(map);
// multimap maps ["a" => {1}, "b" => {1}, "c" => {2}]
Multimap<Integer, String> inverse = Multimaps.invertFrom(multimap, HashMultimap.<Integer, String> create());
// inverse maps [1 => {"a", "b"}, 2 => {"c"}]
四、Tables
Tables类提供了一些方便的实用程序。
1、customTable
与Multimaps.newXXXMultimap(Map,Supplier)实用程序类似,Tables.newCustomTable(Map,供应商<Map>)允许您使用任何喜欢的行或列映射指定表实现。
// use LinkedHashMaps instead of HashMaps
Table<String, Character, Integer> table = Tables.newCustomTable(
Maps.<String, Map<Character, Integer>>newLinkedHashMap(),
new Supplier<Map<Character, Integer>> () {
public Map<Character, Integer> get() {
return Maps.newLinkedHashMap();
}
});