【Guava】集合工具Collections2
Collections2
private Collections2() {}
私有构造器,也没有静态构造器,所以可以很明确它是一个纯工具类了。
filter过滤方法
传入一个带过滤的容器,和一个实现过滤规则的函数类,返回一个带有过滤动作的容器
public static <E extends @Nullable Object> Collection<E> filter( Collection<E> unfiltered, Predicate<? super E> predicate) { if (unfiltered instanceof FilteredCollection) { // Support clear(), removeAll(), and retainAll() when filtering a filtered // collection. return ((FilteredCollection<E>) unfiltered).createCombined(predicate); } return new FilteredCollection<E>(checkNotNull(unfiltered), checkNotNull(predicate));}
如果是Collections2.FilteredCollection类,则直接转型到Collections2.FilteredCollection,然后返回这个类。如果不是Collections2.FilteredCollection,则new一个,将传入的容器和规则传入。
static class FilteredCollection<E extends @Nullable Object> extends AbstractCollection<E> { // 存储待处理的集合 final Collection<E> unfiltered; //存储过滤规则 final Predicate<? super E> predicate; FilteredCollection(Collection<E> unfiltered, Predicate<? super E> predicate) { this.unfiltered = unfiltered; this.predicate = predicate; } //根据新的过滤规则和原来的过滤规则合并创建一个新的容器 FilteredCollection<E> createCombined(Predicate<? super E> newPredicate) { return new FilteredCollection<E>(unfiltered, Predicates.<E>and(predicate, newPredicate)); // .<E> above needed to compile in JDK 5 } //添加元素方法 @Override public boolean add(@ParametricNullness E element) { //根据过滤规则进行测试是否符合,如果符合便进行添加 checkArgument(predicate.apply(element)); return unfiltered.add(element); } //添加一个容器中所有元素 @Override public boolean addAll(Collection<? extends E> collection) { //遍历容器,并对每一个容器进行筛选 for (E element : collection) { checkArgument(predicate.apply(element)); } //如果都满足就添加 return unfiltered.addAll(collection); } //...其他方法}
转型方法
传入一个转型的类,再传入一个转型规则
public static <F extends @Nullable Object, T extends @Nullable Object> Collection<T> transform( Collection<F> fromCollection, Function<? super F, T> function) { return new TransformedCollection<>(fromCollection, function);}
static class TransformedCollection<F extends @Nullable Object, T extends @Nullable Object> extends AbstractCollection<T> { //需要转型的容器 final Collection<F> fromCollection; //转型规则 final Function<? super F, ? extends T> function; TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function) { this.fromCollection = checkNotNull(fromCollection); this.function = checkNotNull(function); } //根据转型规则进行迭代 @Override public Iterator<T> iterator() { return Iterators.transform(fromCollection.iterator(), function); } //...其他方法}
有序排列方法
//第一种是调用了第二种public static <E extends Comparable<? super E>> Collection<List<E>> orderedPermutations(Iterable<E> elements) { return orderedPermutations(elements, Ordering.natural());}//第二种直接创建了Collections2.OrderedPermutationCollection类public static <E> Collection<List<E>> orderedPermutations(Iterable<E> elements, Comparator<? super E> comparator) { return new Collections2.OrderedPermutationCollection(elements, comparator);}
private static final class OrderedPermutationCollection<E> extends AbstractCollection<List<E>> { //不可变集合 final ImmutableList<E> inputList; //比较器 final Comparator<? super E> comparator; final int size; OrderedPermutationCollection(Iterable<E> input, Comparator<? super E> comparator) { this.inputList = ImmutableList.sortedCopyOf(comparator, input); this.comparator = comparator; this.size = calculateSize(inputList, comparator); } /** * The number of permutations with repeated elements is calculated as follows: * * <ul> * <li>For an empty list, it is 1 (base case).对于空列表,它是1(基线条件)。 * <li>When r numbers are added to a list of n-r elements, the number of permutations is * increased by a factor of (n choose r).
当向n-r个元素的列表中添加r个数字时,排列的次数是(n choose r)的倍数。 * </ul> */ private static <E> int calculateSize( List<E> sortedInputList, Comparator<? super E> comparator) { int permutations = 1;//用于存储排列数,初始值为1 int n = 1;//用于追踪当前元素的索引位置,初始值为1 int r = 1;//用于追踪当前重复元素的次数,初始值为1 while (n < sortedInputList.size()) { //使用比较器比较索引为n-1和n的元素 int comparison = comparator.compare(sortedInputList.get(n - 1), sortedInputList.get(n)); if (comparison < 0) {//如果索引n-1的元素小于索引n的元素 // We move to the next non-repeated element. //更新排列数。 //IntMath.binomial用于计算二项式系数的函数 //IntMath.saturatedMultiply 用于计算两数相乘,但不会溢出int的最大最小值 permutations = IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); r = 0;//重置r=0 if (permutations == Integer.MAX_VALUE) { return Integer.MAX_VALUE; } } n++; r++; } return IntMath.saturatedMultiply(permutations, IntMath.binomial(n, r)); } @Override public Iterator<List<E>> iterator() { return new OrderedPermutationIterator<E>(inputList, comparator); } //..。其他方法 }