web-dev-qa-db-fra.com

Comment diviser une liste de tableaux en parties égales?

Est-il possible de scinder ArrayList en différentes parties sans en connaître la taille avant l'exécution? Je sais qu'il existe une méthode appelée:

list.subList(a,b);

mais nous avons besoin de mentionner explicitement le début et la fin de la liste ..__ Mon problème est que nous avons un arraylist contenant des numéros de compte qui contient des données comme 2000,4000 numéros de comptes Je dois passer cet accès dans la requête IN de PL/SQL, car IN ne prend pas en charge plus de 1000 valeurs. J'essaie de scinder en plusieurs morceaux et de l'envoyer à la requête.

Remarque: je ne peux utiliser aucune bibliothèque externe telle que Guava, etc.: ( Tout guide à cet égard est apprécié.

22
Pradeep Simha

Cela devrait vous donner toutes vos pièces:

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())));
}
62
Subodh

fonction générique:

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

profitez-en ~ :)

12
HenryChuang

Java 8 (pas que cela présente des avantages):

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

Taille du groupe:

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

Dans le style ancien:

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

Dans un nouveau style:

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

Merci à @StuartMarks pour la liste oubliée.

5
Joop Eggen

Si vous êtes limité par les limites in de PL/SQL, vous souhaitez savoir comment scinder une liste en fragments de taille <= n , où n est la limite. C’est un problème beaucoup plus simple car il ne nécessite pas nécessite de connaître la taille de la liste à l’avance.

Pseudocode:

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

Si vous avez déjà ajouté la bibliothèque Guava ou ne vous en dérange pas, vous n'avez pas besoin de réinventer la roue.

Il suffit de faire: final List<List<String>> splittedList = Lists.partition(bigList, 10);

bigList implémente l'interface List et 10 est la taille souhaitée de chaque sous-liste (la dernière peut être plus petite)

2
dazito

Le code suivant:

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

produit la sortie suivante:

  //[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]  
0
Medium core
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)
}

Vous pouvez utiliser ce finaliste car il contient la liste des morceaux de oldList.

0
Srinivas B

Je fais aussi la correspondance clé: valeur pour les valeurs avec index. 

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

Sortie:

Liste partitionnée: [[1, 2], [7, 4], [0, 77], [34]]

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

0
Akhil Singhal