[Guava]-使用Iterators进行分组时遇见的坑

原创
2018/04/03 15:33
阅读数 818

平常我们需要对一个大的list进行分批操作,一般使用Iterators#partition和paddedPartition方法(也可以使用Lists#partition)具体使用方式:

List<Order> result = Lists.newArrayListWithCapacity(orders.size());
for (List<String> orderList : Iterables.paddedPartition(orders, DEFAULT_MAX_SIZE)) {
    //doSometime.....
}

使用paddedPartition会出现一个问题,当最后一批的数据小于DEFAULT_MAX_SIZE时候,会把剩下的数据填充为null,比如

list = [1,2,3,4,5] -------paddedPartition(list,3)-------->[[1,2],[3,4],[5,null]]

我们看下源码

public static <T> UnmodifiableIterator<List<T>> paddedPartition(Iterator<T> iterator, int size) {
    return partitionImpl(iterator, size, true);
  }

  private static <T> UnmodifiableIterator<List<T>> partitionImpl(
      final Iterator<T> iterator, final int size, final boolean pad) {
    checkNotNull(iterator);
    checkArgument(size > 0);
    return new UnmodifiableIterator<List<T>>() {
      @Override
      public boolean hasNext() {
        return iterator.hasNext();
      }

      @Override
      public List<T> next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        Object[] array = new Object[size];
        int count = 0;
        for (; count < size && iterator.hasNext(); count++) {
          array[count] = iterator.next();
        }
        for (int i = count; i < size; i++) {
          array[i] = null; // 这里重点,在这一步会判断下最后一页的剩余数据设置为null
        }

        @SuppressWarnings("unchecked") // we only put Ts in it
        List<T> list = Collections.unmodifiableList((List<T>) Arrays.asList(array));
      // 这里会根据pad 判断是否返回list 还是 重新生成一个list 
        return (pad || count == size) ? list : list.subList(0, count);
      }
    };
  }

我们再看下他的孪生的方法

 public static <T> UnmodifiableIterator<List<T>> partition(Iterator<T> iterator, int size) {
    return partitionImpl(iterator, size, false);
  }

都是使用的同一个方法 一个pad(填充)设置为true,一个设置的false

另外,上面我们提到过Lists#partition的方法,他的做法是构建两个新的类实现的

public static <T> List<List<T>> partition(List<T> list, int size) {
    checkNotNull(list);
    checkArgument(size > 0);
    return (list instanceof RandomAccess)
        ? new RandomAccessPartition<T>(list, size)
        : new Partition<T>(list, size);
  }
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部