Подтвердить что ты не робот

Как разбить список массивов на равные части?

Разве можно разделить ArrayList на разные части, не зная его размер до времени выполнения? Я знаю, что есть метод:

list.subList(a,b);

но нам нужно явно указать список и конец списка. Моя проблема заключается в том, что у нас есть arraylist, содержащий номера учетных записей, которые имеют данные, такие как 2000,4000 номеров учетных записей (там номера не будут известны во время кодирования), и мне нужно передать эти accnos в IN-запрос PL/SQL, так как IN не поддерживает более 1000 значений в нем, я пытаюсь разбить на несколько кусков и отправить его в запрос

Примечание. Я не могу использовать внешние библиотеки, такие как Guava и т.д.:( Любое руководство в этом отношении приветствуется.

4b9b3361

Ответ 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())));
}

Ответ 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(3 * i, Math.min(3 * i + 3, list.size())))
        .collect(Collectors.toList());

Благодаря @StuartMarks для забытого списка toList.

Ответ 4

Если вы ограничены ограничениями PL/SQL in, то вы хотите знать, как разбить список на куски размера <= n, где 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<List<String>> 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, поскольку он содержит список chuncks старого списка.

Ответ 7

Я также делаю ключевое: отображение значений для значений с индексом.

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