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

平常我们需要对一个大的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);
  }

转载于:https://my.oschina.net/lowkeysoft/blog/1789307

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值