【问题标题】:Is there a simple way to split ONE list into X sublists?有没有一种简单的方法可以将一个列表拆分为 X 个子列表?
【发布时间】:2013-05-17 19:31:18
【问题描述】:

我有一个大于 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 条记录。

【问题讨论】:

  • 你想要一定数量的子列表还是每个子列表都有一定的长度?
  • 目前我最多需要 5 个列表,然后在每个列表中都有大约相等数量的记录。
  • 您提到子列表的长度为length,有些的长度为length + 1。这些超长列表应该是第一个子列表、最后一个子列表、每隔一个子列表还是其他一些排列?

标签: java list sublist


【解决方案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.");
    }

    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;
}

【讨论】:

    【解决方案2】:

    这是对 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;
    

    }

    【讨论】:

      【解决方案3】:

      如果要保持大列表在每个子列表中的顺序,请尝试以下操作:

      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;
      }
      

      【讨论】:

      • 如果我没看错的话,这实际上会创建 6 个子列表。
      【解决方案4】:

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

      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;
      }
      

      }

      【讨论】:

        【解决方案5】:

        试试这个来维护子列表中主列表的顺序。

        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;
        }
        

        【讨论】:

          猜你喜欢
          • 2020-02-16
          • 2020-11-16
          • 2010-10-07
          • 2010-09-24
          • 1970-01-01
          • 1970-01-01
          • 2015-06-21
          • 1970-01-01
          • 2013-02-21
          相关资源
          最近更新 更多