首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Lists.partition或Iterable.partition将集合拆分为子集

使用Lists.partition或Iterable.partition将集合拆分为子集
EN

Stack Overflow用户
提问于 2016-08-08 11:46:18
回答 1查看 7.3K关注 0票数 5

我想知道将一个集合分割成子集的有效方法是什么?

代码语言:javascript
运行
复制
Iterable<List<Long>> partitions = Iterables.partition(numbers, 10);

代码语言:javascript
运行
复制
List<List<Long>> partitions = Lists.partition(numbers, 10);

时间复杂性有什么不同?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-08 12:07:39

让我们看一下内部实现

方法分区()用于迭代

代码语言:javascript
运行
复制
529  public static <T> Iterable<List<T>> partition(final Iterable<T> iterable, final int size) {
530    checkNotNull(iterable);
531    checkArgument(size > 0);
532    return new FluentIterable<List<T>>() {
533      @Override
534      public Iterator<List<T>> iterator() {
535        return Iterators.partition(iterable.iterator(), size);
536      }
537    };
538  }

方法分区()用于列表

代码语言:javascript
运行
复制
681  public static <T> List<List<T>> partition(List<T> list, int size) {
682    checkNotNull(list);
683    checkArgument(size > 0);
684    return (list instanceof RandomAccess)
685        ? new RandomAccessPartition<T>(list, size)
686        : new Partition<T>(list, size);
687  }

在上面的两个实现中,如果分析代码,Lists检查list instanceof RandomAccess,如果是真的,则使用RandomAccess接口来计算分区。

现在,如果我们看到文档 of RandomAccess:

公共接口RandomAccess List实现所使用的标记接口,用于指示它们支持快速(通常是恒定时间)随机访问。该接口的主要目的是允许通用算法改变其行为,以便在应用于随机或顺序访问列表时提供良好的性能。

所以,我想后者有更好的表现。

如果我们的list不是RandomAccess接口的实例呢?

Lists用于执行分区的核心类(来源)

代码语言:javascript
运行
复制
689  private static class Partition<T> extends AbstractList<List<T>> {
690    final List<T> list;
691    final int size;
692
693    Partition(List<T> list, int size) {
694      this.list = list;
695      this.size = size;
696    }
697
698    @Override
699    public List<T> get(int index) {
700      checkElementIndex(index, size());
701      int start = index * size;
702      int end = Math.min(start + size, list.size());
703      return list.subList(start, end);
704    }
705
706    @Override
707    public int size() {
708      return IntMath.divide(list.size(), size, RoundingMode.CEILING);
709    }
710
711    @Override
712    public boolean isEmpty() {
713      return list.isEmpty();
714    }
715  }

以及Iterators用于执行分区的核心类(来源)。

代码语言:javascript
运行
复制
605  private static <T> UnmodifiableIterator<List<T>> partitionImpl(
606      final Iterator<T> iterator, final int size, final boolean pad) {
607    checkNotNull(iterator);
608    checkArgument(size > 0);
609    return new UnmodifiableIterator<List<T>>() {
610      @Override
611      public boolean hasNext() {
612        return iterator.hasNext();
613      }
614      @Override
615      public List<T> next() {
616        if (!hasNext()) {
617          throw new NoSuchElementException();
618        }
619        Object[] array = new Object[size];
620        int count = 0;
621        for (; count < size && iterator.hasNext(); count++) {
622          array[count] = iterator.next();
623        }
624        for (int i = count; i < size; i++) {
625          array[i] = null; // for GWT
626        }
627
628        @SuppressWarnings("unchecked") // we only put Ts in it
629        List<T> list = Collections.unmodifiableList(
630            (List<T>) Arrays.asList(array));
631        return (pad || count == size) ? list : list.subList(0, count);
632      }
633    };
634  }

现在,如果我们分析最后两个代码,对于任何人来说,如果不进行全面的分析,就很难找到更好的方法。但是,我们可以说,如果我们的列表是RandomAccess接口的一个实例,那么肯定Lists.partition(lists, pivot);更快。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38828405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档