将列表划分为n个大小的列表的有效方法

Row*_*awn 51 java partitioning arraylist

我有一个数组,我想分成更小的n个数组,并对每个数组执行操作.我目前的做法是

用Java中的ArrayLists实现(任何伪代码都可以)

    for (int i = 1; i <= Math.floor((A.size() / n)); i++) {
            ArrayList temp = subArray(A, ((i * n) - n),
                    (i * n) - 1);
            // do stuff with temp
        }

    private ArrayList<Comparable> subArray(ArrayList A, int start,
                int end) {
            ArrayList toReturn = new ArrayList();
            for (int i = start; i <= end; i++) {
                toReturn.add(A.get(i));
            }
            return toReturn;
        }
Run Code Online (Sandbox Code Playgroud)

其中A是列表,n是所需列表的大小

我相信这种方式在处理相当大的列表(大小高达100万)时花费了太多时间,所以我试图弄清楚什么会更有效率.

Col*_*inD 100

您将要使用List.subList(int,int)视图而不是复制每个子列表.要轻松地执行此操作,请使用GuavaLists.partition(List,int)方法:

List<Foo> foos = ...
for (List<Foo> partition : Lists.partition(foos, n)) {
  // do something with partition
}
Run Code Online (Sandbox Code Playgroud)

请注意,这与许多事情一样,效率List不高RandomAccess(例如a LinkedList).

  • 如果你有一个Iterable而不是List,那么还有Iterables.partition(Iterable,int)。 (2认同)

小智 14

如果您正在使用列表,我使用" Apache Commons Collections 4 "库.它在ListUtils类中有一个分区方法:

...
int targetSize = 100;
List<Integer> largeList = ...
List<List<Integer>> output = ListUtils.partition(largeList, targetSize);
Run Code Online (Sandbox Code Playgroud)

此方法改编自http://code.google.com/p/guava-libraries/


rhe*_*ser 14

例如:

    int partitionSize = 10;
    List<List<String>> partitions = new ArrayList<>();

    for (int i=0; i<yourlist.size(); i += partitionSize) {
        partitions.add(yourlist.subList(i, Math.min(i + partitionSize, yourlist.size())));
    }

    for (List<String> list : partitions) {
        //Do your stuff on each sub list
    }
Run Code Online (Sandbox Code Playgroud)

  • 绝对是最佳答案 (2认同)

Ans*_*ava 8

如果您不想使用库,这是我的解决方案

1.分成N等份:

private <T> List<List<T>> nPartition(List<T> objs, final int N) {
    return new ArrayList<>(IntStream.range(0, objs.size()).boxed().collect(
            Collectors.groupingBy(e->e%N,Collectors.mapping(e->objs.get(e), Collectors.toList())
                    )).values());
}
Run Code Online (Sandbox Code Playgroud)

2. 划分为 N 个项目的集合:

private <T> List<List<T>> nPartition(List<T> objs, final int N) {
    return new ArrayList<>(IntStream.range(0, objs.size()).boxed().collect(
            Collectors.groupingBy(e->e/N,Collectors.mapping(e->objs.get(e), Collectors.toList())
                    )).values());
    }
Run Code Online (Sandbox Code Playgroud)

在这里行动:https : //ideone.com/QiQnbE


Ice*_*erg 6

// 测试数据

List<Integer> list = Arrays.asList(0, 1, 2,     3, 4, 5,    6, 7, 8,    9);
int n = 3;
Run Code Online (Sandbox Code Playgroud)

// 一行(语句)包含 java 8 流和 list.subList

List<List<Integer>> partitions = IntStream.range(0, list.size())
    .filter(i -> i % n == 0)
    .mapToObj(i -> list.subList(i, Math.min(i + n, list.size() )))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)


alp*_*ian 5

好吧,在看到 ColinD 的答案(+1)之前我自己写了一个,使用 Guava 绝对是可行的方法。留下来太有趣了,所以下面给你的是列表的副本而不是视图,所以 GUava 肯定比这更有效率。我发布这篇文章是因为写起来很有趣,而不是暗示它同样有效:

Hamcrest 测试(无论如何之一):

assertThat(chunk(asList("a", "b", "c", "d", "e"), 2), 
           equalTo(asList(asList("a", "b"), asList("c", "d"), asList("e"))));
Run Code Online (Sandbox Code Playgroud)

代码:

public static <T> Iterable<Iterable<T>> chunk(Iterable<T> in, int size) {
    List<Iterable<T>> lists = new ArrayList();
    Iterator<T> i = in.iterator();
    while (i.hasNext()) {
        List<T> list = new ArrayList();
        for (int j=0; i.hasNext() && j<size; j++) {
            list.add(i.next());
        }
        lists.add(list);
    }
    return lists;
}
Run Code Online (Sandbox Code Playgroud)