赞
踩
任何具有JDK Collections Framework经验的程序员都知道并喜欢java.util.Collections.Guava提供了更多的实用程序:适用于所有集合的静态方法。这些是番石榴最受欢迎和成熟的部分。
对应于特定接口的方法以相对直观的方式分组:
nterface | JDK or Guava? | Corresponding Guava utility class |
Collection | JDK | Collections2 |
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 |
在JDK 7之前,构建新的泛型集合需要令人不愉快的代码复制:
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<TypeThatsTooLongForItsOwnGood>();
我想我们都可以同意,这是令人不愉快的。Guava提供了使用泛型来推断右侧类型的静态方法:
- List<TypeThatsTooLongForItsOwnGood> list = Lists.newArrayList();
- Map<KeyType, LongishValueType> map = Maps.newLinkedHashMap();
可以肯定的是,JDK 7中的菱形操作符减少了这方面的麻烦:
List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<>();
但Guava走得更远。使用工厂方法模式,我们可以非常方便地用集合的起始元素来初始化集合。
- Set<Type> copySet = Sets.newHashSet(elements);
- List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
此外,通过命名工厂方法(有效Java项1),我们可以提高将集合初始化为大小的可读性:
- List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
- List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
- Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);
下面列出了提供的精确静态工厂方法及其相应的实用程序类。
注意:Guava引入的新集合类型不公开原始构造函数,或者在实用程序类中具有初始值设定项。相反,它们直接公开静态工厂方法,例如:
Multiset<String> multiset = HashMultiset.create();
只要可能,Guava更喜欢提供接受Iterable而不是Collection的实用程序。在谷歌,遇到一个“集合”并不罕见,它实际上没有存储在主存中,而是从数据库或另一个数据中心收集的,并且在不实际获取所有元素的情况下无法支持size()等操作。
因此,您可能希望看到的所有集合都支持的许多操作都可以在Iterables中找到。此外,大多数Iterables方法在iterator中都有一个接受原始迭代器的相应版本。
Iterables类中的绝大多数操作都是懒惰的:它们只在绝对必要的时候推进支持迭代。返回Iterables的方法返回延迟计算的视图,而不是在内存中显式地构造集合。
从Guava 12开始,Iterables由FluentInterable类补充,该类封装了Iterable,并为其中许多操作提供了“流畅”的语法。
以下是最常用的实用程序的选择,尽管在Guava函数习语中讨论了Iterables中许多更“函数”的方法。
Method | Description | See Also |
concat(Iterable<Iterable>) | 返回几个可迭代项的串联的惰性视图。 | concat(Iterable...) |
frequency(Iterable, Object) | 返回对象的出现次数。 | Compare Collections.frequency(Collection, Object); see Multiset |
partition(Iterable, int) | 返回一个不可修改的可迭代视图,该视图被划分为指定大小的块。 | Lists.partition(List, int), paddedPartition(Iterable, int) |
getFirst(Iterable, T default) | 返回可迭代项的第一个元素,如果为空,则返回默认值。 | Compare Iterable.iterator().next(), FluentIterable.first() |
getLast(Iterable) | 返回可迭代项的最后一个元素,如果它为空,则会以NoSuchElementException快速失败。 | getLast(Iterable, T default), FluentIterable.last() |
elementsEqual(Iterable, Iterable) | 如果可迭代项具有相同顺序的相同元素,则返回true。 | Compare List.equals(Object) |
unmodifiableIterable(Iterable) | 返回可迭代项的不可修改视图。 | Compare Collections.unmodifiableCollection(Collection) |
limit(Iterable, int) | 返回一个Iterable,最多返回指定数量的元素。 | FluentIterable.limit(int) |
getOnlyElement(Iterable) | 返回Iterable中唯一的元素。如果可迭代项为空或具有多个元素,则快速失败。 | getOnlyElement(Iterable, T default) |
- Iterable<Integer> concatenated = Iterables.concat(
- Ints.asList(1, 2, 3),
- Ints.asList(4, 5, 6));
- // concatenated has elements 1, 2, 3, 4, 5, 6
-
- String lastAdded = Iterables.getLast(myLinkedHashSet);
-
- String theElement = Iterables.getOnlyElement(thisSetIsDefinitelyASingleton);
- // if this set isn't a singleton, something is wrong!
通常,集合在其他集合上自然支持这些操作,但在可迭代对象上不支持。
当输入实际上是Collection时,这些操作中的每一个都委托给相应的Collection接口方法。例如,如果向Iterables.size传递Collection,它将调用Collection.size方法,而不是遍历迭代器。
Method | Analogous Collection method | FluentIterable equivalent |
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() |
除了上面介绍的方法和函数习语[article]functional中的方法外,FluentTerable还有一些方便的方法可以复制到不可变集合中:
Result Type | Method |
ImmutableList | toImmutableList() |
ImmutableSet | toImmutableSet() |
ImmutableSortedSet | toImmutableSortedSet(Comparator) |
除了静态构造函数方法和函数式编程方法外,Lists还为List对象提供了许多有价值的实用程序方法。
Method | Description |
partition(List, int) | 返回基础列表的视图,该视图被划分为指定大小的块。 |
reverse(List) | 返回指定列表的反向视图。注意:如果列表是不可变的,请考虑使用ImmutableList.reverse()。 |
- 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}}
Sets实用程序类包括许多的方法。
我们提供了许多标准的集合论运算,实现为对参数集的视图。这些返回一个SetView,它可以用于:
Method |
union(Set, Set) |
intersection(Set, Set) |
difference(Set, Set) |
symmetricDifference(Set, Set) |
- 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();
Method | Description | See Also |
cartesianProduct(List<Set>) | 返回通过从每个集合中选择一个元素可以获得的所有可能的列表。 | cartesianProduct(Set...) |
powerSet(Set) | 返回指定集合的子集集。 |
- Set<String> animals = ImmutableSet.of("gerbil", "hamster");
- Set<String> fruits = ImmutableSet.of("apple", "orange", "banana");
-
- Set<List<String>> product = Sets.cartesianProduct(animals, fruits);
- // {{"gerbil", "apple"}, {"gerbil", "orange"}, {"gerbil", "banana"},
- // {"hamster", "apple"}, {"hamster", "orange"}, {"hamster", "banana"}}
-
- Set<Set<String>> animalSets = Sets.powerSet(animals);
- // {{}, {"gerbil"}, {"hamster"}, {"gerbil", "hamster"}}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。