【问题标题】:How to split array list into equal parts?如何将数组列表分成相等的部分?
【发布时间】:2012-11-20 15:09:42
【问题描述】:

有没有办法将 ArrayList 拆分成不同的部分,直到运行时才知道它的大小?我知道有一个方法叫:

list.subList(a,b);

但我们需要明确提及列表的起始和结束范围。 我的问题是,我们得到一个包含帐号的数组列表,其中包含 2000,4000 个帐号之类的数据(在编码期间不会知道这些数字),我需要将此 acc nos 传递给 PL/SQL 的 IN 查询,如IN 不支持超过 1000 个值,我正在尝试拆分为多个块并将其发送到查询

注意:我不能使用任何外部库,如 Guava 等。:( 感谢您提供这方面的任何指南。

【问题讨论】:

  • 你不能做list.size()然后从那里去吗?
  • list.size() 将在运行时获取列表的大小。你不必担心这一点。您可以使用它并将数组列表拆分为您想要的大小的块。
  • @SrinivasB,但是没有可用的 API 方法可以根据我想要的大小来拆分它?我需要明确提及范围
  • 我已经贴出了生成分区的代码,下面查看。
  • @pradeepsimha:嗨,我在下面给出了我的代码。检查并告诉我。

标签: java plsql oracle10g


【解决方案1】:

这应该给你所有的部分:

int partitionSize = 1000;
List<List<Integer>> partitions = new LinkedList<List<Integer>>();
for (int i = 0; i < originalList.size(); i += partitionSize) {
    partitions.add(originalList.subList(i,
            Math.min(i + partitionSize, originalList.size())));
}

【讨论】:

  • 不应该是Math.min(i + partitionSize, originalList.size() - i)吗?
  • 我觉得应该是Math.min(i + partitionSize, originalList.size())
  • 我已根据 Jonathan Gawrych 的建议进行了编辑。它比 i + Math.min(partitionSize, originalList.size() - i) 的原始版本更容易混淆(注意那里额外减去了 i)。
【解决方案2】:

通用函数:

public static <T> ArrayList<T[]> chunks(ArrayList<T> bigList,int n){
    ArrayList<T[]> chunks = new ArrayList<T[]>();

    for (int i = 0; i < bigList.size(); i += n) {
        T[] chunk = (T[])bigList.subList(i, Math.min(bigList.size(), i + n)).toArray();         
        chunks.add(chunk);
    }

    return chunks;
}

好好享受吧~ :)

【讨论】:

    【解决方案3】:

    Java 8(不是说它有优势):

    List<String> list = new ArrayList<>();
    Collections.addAll(list,  "a","b","c","b","c","a","c","a","b");
    

    分组大小:

    final int G = 3;
    final int NG = (list.size() + G - 1) / G;
    

    旧式:

    List<List<String>> result = new ArrayList(NG);
    IntStream.range(0, list.size())
        .forEach(i -> {
            if (i % G == 0) {
                result.add(i/G, new ArrayList<>());
            }
            result.get(i/G).add(list.get(i));
        });
    

    新风格:

    List<List<String>> result = IntStream.range(0, NG)
        .mapToObj(i -> list.subList(G * i, Math.min(G * i + G, list.size())))
        .collect(Collectors.toList());
    

    感谢@StuartMarks 忘记了toList。

    【讨论】:

    • 我认为你可以使用Collectors.toList()作为收集器。
    • @StuartMarks 我已经用过几次了,但是在这里忘记了。
    • 嗯,我认为在“新风格”中,3 应该是G,不是吗?
    • @FrançoisBeausoleil 是的,自然。
    【解决方案4】:

    如果您受到 PL/SQL in 限制,那么您想知道如何将列表拆分为大小为 的块,其中 n是极限。这是一个简单得多的问题,因为它不需要提前知道列表的大小。

    伪代码:

    for (int n=0; n<list.size(); n+=limit)
    {
        chunkSize = min(list.size,n+limit);
        chunk     = list.sublist(n,chunkSize);
        // do something with chunk
    }
    

    【讨论】:

    • 是的,我正在寻找将列表拆分为大小
    【解决方案5】:

    如果您已经拥有或不介意添加 Guava 库,则无需重新发明轮子。

    只需:final List&lt;List&lt;String&gt;&gt; splittedList = Lists.partition(bigList, 10);

    其中bigList 实现List 接口,10 是每个子列表的所需大小(最后一个可能更小)

    【讨论】:

      【解决方案6】:
      listSize = oldlist.size();
      chunksize =1000;
      chunks = list.size()/chunksize;
      ArrayList subLists;
      ArrayList finalList;
      int count = -1;
      for(int i=0;i<chunks;i++){
           subLists = new ArrayList();
           int j=0;
           while(j<chunksize && count<listSize){
              subList.add(oldList.get(++count))
              j++;
           }
           finalList.add(subLists)
      }
      

      您可以使用这个 finalList,因为它包含 oldList 的块列表。

      【讨论】:

        【解决方案7】:

        我也在为带有索引的值做 key:value 映射。

          public static void partitionOfList(List<Object> l1, List<Object> l2, int partitionSize){
                    Map<String, List<Object>> mapListData = new LinkedHashMap<String, List<Object>>();
                    List<Object> partitions = new LinkedList<Object>();
                    for (int i = 0; i < l1.size(); i += partitionSize) {
                        partitions.add(l1.subList(i,Math.min(i + partitionSize, l1.size())));
                        l2=new ArrayList(partitions);
                    }
                    int l2size = l2.size();
                    System.out.println("Partitioned List: "+l2);
                    int j=1;
                    for(int k=0;k<l2size;k++){
                         l2=(List<Object>) partitions.get(k);
                        // System.out.println(l2.size());
                         if(l2.size()>=partitionSize && l2.size()!=1){
                        mapListData.put("val"+j+"-val"+(j+partitionSize-1), l2);
                        j=j+partitionSize;
                         }
                         else if(l2.size()<=partitionSize && l2.size()!=1){
                            // System.out.println("::::@@::"+ l2.size());
                             int s = l2.size();
                             mapListData.put("val"+j+"-val"+(j+s-1), l2);
                                //k++;
                                j=j+partitionSize;
                         }
                         else if(l2.size()==1){
                            // System.out.println("::::::"+ l2.size());
                             //int s = l2.size();
                             mapListData.put("val"+j, l2);
                                //k++;
                                j=j+partitionSize;
                         }
                    }
                    System.out.println("Map: " +mapListData);
                }
            
            public static void main(String[] args) {
                    List l1 = new LinkedList();
                    l1.add(1);
                    l1.add(2);
                    l1.add(7);
                    l1.add(4);
                    l1.add(0);
                    l1.add(77);
                    l1.add(34);
            
            partitionOfList(l1,l2,2);
            }
        

        输出:

        分区列表:[[1, 2], [7, 4], [0, 77], [34]]

        地图:{val1-val2=[1, 2], val3-val4=[7, 4], val5-val6=[0, 77], val7=[34]}

        【讨论】:

          【解决方案8】:

          以下代码:

          private static List<List<Object>> createBatch(List<Object> originalList, int batch_size) {
              int Length = originalList.size();
              int chunkSize = Length / batch_size;
              int residual = Length-chunkSize*batch_size;
              List<Integer> list_nums = new ArrayList<Integer>();
              for (int i = 0; i < batch_size; i++) {
                  list_nums.add(chunkSize);
              }
              for (int i = 0; i < residual; i++) {
                  list_nums.set(i, list_nums.get(i) + 1);
              }
              List<Integer> list_index = new ArrayList<Integer>();
              int cumulative = 0;
              for (int i = 0; i < batch_size; i++) {
                  list_index.add(cumulative);
                  cumulative += list_nums.get(i);
              }
              list_index.add(cumulative);
              List<List<Object>> listOfChunks = new ArrayList<List<Object>>();
              for (int i = 0; i < batch_size; i++) {
                  listOfChunks.add(originalList.subList(list_index.get(i), list_index.get(i + 1)));
              }
              return listOfChunks;
          }
          

          产生以下输出:

            //[0,..,99] equally partition into 6 batch
            // result:batch_size=[17,17,17,17,16,16]
            //Continually partition into 6 batch, and residual also equally 
            //partition into top n batch
            // Output:
            [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]    
            [17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33] 
            [34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50] 
            [51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67] 
            [68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83]       
            [84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99]  
          

          【讨论】:

            【解决方案9】:

            通用方法为您提供帮助:

            private static List<List<Object>> createBatch(List<Object> originalList,
                    int chunkSize) {
                List<List<Object>> listOfChunks = new ArrayList<List<Object>>();
                for (int i = 0; i < originalList.size() / chunkSize; i++) {
                    listOfChunks.add(originalList.subList(i * chunkSize, i * chunkSize
                            + chunkSize));
                }
                if (originalList.size() % chunkSize != 0) {
                    listOfChunks.add(originalList.subList(originalList.size()
                            - originalList.size() % chunkSize, originalList.size()));
                }
                return listOfChunks;
            

            【讨论】:

            • 通用但在使用 Object 而不是 Java 泛型时缺少编译时检查
            猜你喜欢
            • 2011-07-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-04
            相关资源
            最近更新 更多