Gibt es überhaupt eine Möglichkeit, ArrayList in verschiedene Teile aufzuteilen, ohne deren Größe bis zur Laufzeit zu kennen? Ich weiß, dass es eine Methode gibt:
list.subList(a,b);
wir müssen jedoch explizit den Anfangs- und Endbereich der Liste erwähnen. Mein Problem ist, dass wir eine Arrayliste mit Kontonummern erhalten, die Daten wie 2000.4000 Kontonummern enthält (deren Nummern während der Codierungszeit nicht bekannt sind) und Ich muss diese accnos an die IN-Abfrage von PL/SQL übergeben, da IN nicht mehr als 1000 Werte darin unterstützt. Ich versuche, in mehrere Chunks aufzuteilen und sie an die Abfrage zu senden
Hinweis: Ich kann keine externen Bibliotheken wie Guava usw. verwenden. ( Alle diesbezüglichen Anleitungen werden geschätzt.
Dies sollte Ihnen alle Ihre Teile geben:
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())));
}
generische Funktion:
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;
}
genieße es ~ :)
Java 8 (nicht dass es Vorteile hat):
List<String> list = new ArrayList<>();
Collections.addAll(list, "a","b","c","b","c","a","c","a","b");
Gruppierungsgröße:
final int G = 3;
final int NG = (list.size() + G - 1) / G;
Im alten Stil:
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));
});
Im neuen Stil:
List<List<String>> result = IntStream.range(0, NG)
.mapToObj(i -> list.subList(3 * i, Math.min(3 * i + 3, list.size())))
.collect(Collectors.toList());
Danke an @StuartMarks für die vergessene toList.
Wenn Sie durch in
-Grenzwerte von PL/SQL eingeschränkt sind, möchten Sie wissen, wie eine Liste in Blöcke der Größe <= n aufgeteilt wird, wobei n der Grenzwert ist. Dies ist ein viel einfacheres Problem, da nicht die Größe der Liste im Voraus wissen muss.
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
}
Wenn Sie die Guava-Bibliothek bereits hinzugefügt haben oder nicht, ist es nicht erforderlich, das Rad neu zu erfinden.
Einfach tun: final List<List<String>> splittedList = Lists.partition(bigList, 10);
wobei bigList
die List
-Schnittstelle implementiert und 10
die gewünschte Größe jeder Unterliste ist (die letzte kann kleiner sein)
Der folgende Code:
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;
}
erzeugt die folgende Ausgabe:
//[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)
}
Sie können diesen Finalisten verwenden, da er die Liste der Chunks der alten Liste enthält.
Ich mache auch Schlüssel: Wertemapping für Werte mit 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);
}
Ausgabe:
Partitionierte Liste: [[1, 2], [7, 4], [0, 77], [34]]
Karte: {val1-val2 = [1,2], val3-val4 = [7, 4], val5-val6 = [0, 77], val7 = [34]}