有没有一种简单的方法将一个列表拆分为X个子列表?

时间:2013-05-17 19:31:18

标签: java list sublist

我有一个大于20k的随机大小列表。如何将它们拆分为子列表,其中每个子列表将具有相等的长度或相等的长度+ 1(对于奇数列表?)?

由于它是随机大小,实现不应该有任何定义的大小吗?

我目前正在查看此模板:

public static <T> List<List<T>> split(List<T> list, int size) throws NullPointerException, IllegalArgumentException {
        if (list == null) {
            throw new NullPointerException("The list parameter is null.");
        }
        if (size <= 0) {
            throw new IllegalArgumentException("The size parameter must be more than 0.");
        }

        int num = list.size() / size;
        int mod = list.size() % size;
        List<List<T>> ret = new ArrayList<List<T>>(mod > 0 ? num + 1 : num);
        for (int i = 0; i < num; i++) {
            ret.add(list.subList(i * size, (i + 1) * size));
        }
        if (mod > 0) {
            ret.add(list.subList(num * size, list.size()));
        }
        return ret;
    }

这是基于已知子列表大小创建子列表然后创建X子列表。

我需要的结果是传递LIST和目标sublistSize。所以我传递了一个大小为26346条记录和sublistSize 5的列表。我最终会得到5个子列表。前四个子列表将有5269个记录,最后一个(第五个)子列表将有5270个记录。

5 个答案:

答案 0 :(得分:8)

这个怎么样?这将按照您的说法执行(如果项目的顺序不重要),创建“大小”子列表,它会将所有项目分发到新列表。

public static <T> List<List<T>> split(List<T> list, int size)
        throws NullPointerException, IllegalArgumentException {
    if (list == null) {
        throw new NullPointerException("The list parameter is null.");
    }

    if (size <= 0) {
        throw new IllegalArgumentException(
                "The size parameter must be more than 0.");
    }

    List<List<T>> result = new ArrayList<List<T>>(size);

    for (int i = 0; i < size; i++) {
        result.add(new ArrayList<T>());
    }

    int index = 0;

    for (T t : list) {
        result.get(index).add(t);
        index = (index + 1) % size;
    }

    return result;
}

答案 1 :(得分:1)

这是使用sublist方法优化Hamsar的aproch的改进。

   public static <T> List<List<T>> splitListToSubLists(List<T> parentList, int subListSize) {
  List<List<T>> subLists = new ArrayList<List<T>>();
  if (subListSize > parentList.size()) {
     subLists.add(parentList);
  } else {
     int remainingElements = parentList.size();
     int startIndex = 0;
     int endIndex = subListSize;
     do {
        List<T> subList = parentList.subList(startIndex, endIndex);
        subLists.add(subList);
        startIndex = endIndex;
        if (remainingElements - subListSize >= subListSize) {
           endIndex = startIndex + subListSize;
        } else {
           endIndex = startIndex + remainingElements - subList.size();
        }
        remainingElements -= subList.size();
     } while (remainingElements > 0);

  }
  return subLists;

}

答案 2 :(得分:0)

如果要维护每个子列表中大型列表的顺序,请尝试以下操作:

public static <T> List<List<T>> split(List<T> list, int numberOfLists) {
    if (list == null) {
        throw new NullPointerException("The list parameter is null.");
    }
    if (numberOfLists <= 0) {
        throw new IllegalArgumentException(
                "The number of lists parameter must be more than 0.");
    }

    int sizeOfSubList = list.size() / numberOfLists + 1;
    int remainder = list.size() % numberOfLists;

    List<List<T>> subLists = new ArrayList<List<T>>(numberOfLists);

    // if there is a remainder, let the first sub-lists have one length...
    for (int i = 0; i < numberOfLists - remainder; i++) {
        subLists.add(list.subList(i*sizeOfSubList, (i+1)*sizeOfSubList));
    }

    // ... the remaining sub-lists will have -1 size than the first.
    sizeOfSubList--;
    for (int i = numberOfLists - remainder; i < numberOfLists; i++) {
        subLists.add(list.subList(i*sizeOfSubList, (i+1)*sizeOfSubList));
    }

    return subLists;
}

答案 3 :(得分:0)

这将根据子列表的所需大小将主列表拆分为子列表。

public List splitListToSubList(List<Object> parentList, int childListSize) {
    List<List<Object>> childList = new ArrayList<List<Object>>();
    List<Object> tempList = new ArrayList<Object>();
    int count = 0;
    if (parentList != null) {
        for (Object obj : parentList) {
            if (count < childListSize) {
                count = count + 1;
                tempList.add(obj);
            } else {
                childList.add(tempList);
                tempList = new ArrayList<Object>();
                tempList.add(obj);
                count = 1;
            }

        }
        if (tempList.size() < childListSize) {
            childList.add(tempList);
        }
    }
    return childList;
}

}

答案 4 :(得分:0)

尝试这个来保存子列表中主列表的顺序。

public <T> List<List<T>> orderedSplit(List<T> list, int lists) throws NullPointerException, IllegalArgumentException {
    if (list == null) {
        throw new NullPointerException("La lista es nula.");
    }

    if (lists <= 0) {
        throw new IllegalArgumentException("La lista debe divirse en una cantidad mayor a 0.");
    }

    if(list.size() < lists){
        throw new IllegalArgumentException("El tamaño de la lista no es suficiente para esa distribución.");
    }

    List<List<T>> result = new ArrayList<List<T>>(lists);

    int listsSize = list.size() / lists;
    int remainder = list.size() % lists;

    int index = 0;
    int remainderAccess = 0;
    int from = index*listsSize + remainderAccess;
    int to = (index+1)*listsSize + remainderAccess;

    while(lists > index){

        if(remainder != 0){
            result.add(list.subList(from, to+1));
            remainder--;
            remainderAccess++;
        }else {
            result.add(list.subList(from, to));
        }

        index++;
        from = index*listsSize + remainderAccess;
        to = (index+1)*listsSize + remainderAccess;
    }

    return result;
}