2

我有一个大于 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 条记录,最后(第 5 个)子列表将有 5270 条记录。

4

5 回答 5

10

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

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;
}
于 2013-05-17T20:52:35.620 回答
1

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

   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;

}

于 2014-10-29T10:55:04.830 回答
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;
}
于 2013-05-17T20:56:36.540 回答
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;
}

}

于 2014-09-10T16:31:59.220 回答
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;
}
于 2016-02-05T15:03:23.107 回答