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é.
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())));
}
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 ~ :)
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.
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
}
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);
où bigList
implémente l'interface List
et 10
est la taille souhaitée de chaque sous-liste (la dernière peut être plus petite)
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]
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.
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]}