从现有的ArrayList创建大小为N的子列表

时间:2018-08-25 11:23:29

标签: java list arraylist

我正在学习Jjava,并且在ArrayLists上发现了一个有趣的练习。目的是编写一个函数int,该函数接受参数partition()和参数list并返回子列表的列表,其中每个子列表的最大值为{{1} }元素。

例如:

  • size应该返回size
  • partition([1,2,3,4,5], 2)应该返回[ [1,2], [3,4], [5] ]
  • partition([1,2,3,4,5], 3)应该返回[ [1,2,3], [4,5] ]

我这样做了,但是只有在参数partition([1,2,3,4,5], 1)等于[ [1], [2], [3], [4], [5] ]并且我想在所有情况下都这样做时,它才有效,如果有人可以帮助我,我很努力。 / p>

size

2 个答案:

答案 0 :(得分:0)

您可以使用subList方法。

public ArrayList<ArrayList> partition(List<Integer> li, int n) {
    ArrayList<ArrayList> al = new ArrayList();
    int start = 0;
    int i=n;
    for(; i<li.size(); i+=n){
        List<Integer> lis = li.subList(start, i);
        ArrayList<Integer> list = new ArrayList<>();
        list.addAll(lis);
        al.add(list);
        start = i;
    }

    if(i >= li.size()){
        List<Integer> lis = li.subList(start, li.size());
        ArrayList<Integer> list = new ArrayList<>();
        list.addAll(lis);
        al.add(list);
    }
    return al;
}

答案 1 :(得分:0)

我试图了解您的解决方案,但不幸的是我没有理解。您的外部循环是错误的:最外部的循环一定是从0到列表的大小,而不是分区的大小。

下一件事是您的最内层循环。每次您进入内部时,都要创建一个新列表,向其中添加一个元素,然后将此列表添加到结果中。这没有任何意义。您最有可能想要这样的东西(中间循环的主体)

List<Integer> list = new ArrayList<Integer>(n);
for (...) {
    ...
    int b = l.get(j);
    list.add(b);
    ...
}
al.add(list);

但是当您引入了第三个循环时,它仍然不起作用,在这里绝对没有必要。为了使您的解决方案可靠,您仅需要2个循环(第一个-遍历整个列表,第二个遍历当前分区:

public static List<List<Integer>> partition(List<Integer> l, int n) {
    List<List<Integer>> al = new ArrayList<>();
    for (int i = 0; i < l.size(); i += n) {
        List<Integer> list = new ArrayList<>();
        for (int j = i; j < i + n && j < l.size(); j++) {
            list.add(l.get(j));
        }
        al.add(list);
    }
    return al;
}

看一下我选择的边界:外循环从0到列表大小,步长为分区大小,而内循环从外循环的当前索引到分区大小或列表大小,以先到者为准。

有一个更简单的解决方案:

private static List<List<?>> partition(List<?> list, int size) {
    var result = new ArrayList<List<?>>();
    for (int i = 0; i < list.size(); i += size) {
        result.add(new ArrayList<>(list.subList(i, Math.min(i + size, list.size()))));
    }
    return result;
}

这是一种通用方法,您可以传递任何元素的列表(不仅仅是整数)并获得分区结果。这又是一个循环,该循环从0到具有分区大小步长的列表大小,并且每次都根据分区大小或原始元素的子列表(如果少于完整分区的话)获得剩余列表的子列表。

此外,作为旁注。使用接口(List)而不是实现(ArrayList)和通用类型(ArrayList<>()List<Integer>()List<?>而不是原始代码来查看我的代码类型(ArrayList()