跳至主要內容

集合工具 - 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);
    }

    //..。其他方法
  }
seven97官方微信公众号
seven97官方微信公众号