繁体   English   中英

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

[英]Creating a sub-List of size N from an existing ArrayList

我正在学习Jjava,并且在ArrayLists上发现了一个有趣的练习。 目的是编写一个函数partition() ,该函数具有参数list和参数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] ]

我这样做了,但只有在参数size等于1且我想在所有情况下都这样做时,它才起作用,如果有人可以帮助我,我很挣扎。

public static void main(String[] args) {
    Apside t = new Apside();
    ArrayList<Integer> a = new ArrayList<Integer>();
    a.add(1);
    a.add(2);
    a.add(3);
    a.add(4);
    System.out.println(t.partition(a, 1));
}

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



        }
    }
    return al;
}

您可以使用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;
}

我试图了解您的解决方案,但不幸的是我不明白。 您的外部循环是错误的:最外部的循环肯定应该从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() )看一下我的代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM