Jak mogę podzielić ArrayList (rozmiar = 1000) na wiele ArrayList o tym samym rozmiarze (= 10)?
ArrayList<Integer> results;
Jak mogę podzielić ArrayList (rozmiar = 1000) na wiele ArrayList o tym samym rozmiarze (= 10)?
ArrayList<Integer> results;
Odpowiedzi:
Możesz użyć, subList(int fromIndex, int toIndex)aby uzyskać widok części oryginalnej listy.
Z interfejsu API:
Zwraca widok części tej listy między podaną
fromIndex, włącznie itoIndexwyłączną. (JeślifromIndexitoIndexsą równe, zwrócona lista jest pusta). Zwrócona lista jest poparta tą listą, więc zmiany niestrukturalne na zwróconej liście są odzwierciedlone na tej liście i odwrotnie. Zwrócona lista obsługuje wszystkie opcjonalne operacje na liście obsługiwane przez tę listę.
Przykład:
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(5,3,1,2,9,5,0,7)
);
List<Integer> head = numbers.subList(0, 4);
List<Integer> tail = numbers.subList(4, 8);
System.out.println(head); // prints "[5, 3, 1, 2]"
System.out.println(tail); // prints "[9, 5, 0, 7]"
Collections.sort(head);
System.out.println(numbers); // prints "[1, 2, 3, 5, 9, 5, 0, 7]"
tail.add(-1);
System.out.println(numbers); // prints "[1, 2, 3, 5, 9, 5, 0, 7, -1]"
Jeśli potrzebujesz, aby te posiekane listy NIE były widokiem, po prostu utwórz nową Listz subList. Oto przykład połączenia kilku z tych rzeczy:
// chops a list into non-view sublists of length L
static <T> List<List<T>> chopped(List<T> list, final int L) {
List<List<T>> parts = new ArrayList<List<T>>();
final int N = list.size();
for (int i = 0; i < N; i += L) {
parts.add(new ArrayList<T>(
list.subList(i, Math.min(N, i + L)))
);
}
return parts;
}
List<Integer> numbers = Collections.unmodifiableList(
Arrays.asList(5,3,1,2,9,5,0,7)
);
List<List<Integer>> parts = chopped(numbers, 3);
System.out.println(parts); // prints "[[5, 3, 1], [2, 9, 5], [0, 7]]"
parts.get(0).add(-1);
System.out.println(parts); // prints "[[5, 3, 1, -1], [2, 9, 5], [0, 7]]"
System.out.println(numbers); // prints "[5, 3, 1, 2, 9, 5, 0, 7]" (unmodified!)
Możesz dodać bibliotekę Guava do swojego projektu i użyć metody Lists.partition , np
List<Integer> bigList = ...
List<List<Integer>> smallerLists = Lists.partition(bigList, 10);
Apache Commons Collections 4 ma metodę podziału w ListUtilsklasie. Oto jak to działa:
import org.apache.commons.collections4.ListUtils;
...
int targetSize = 100;
List<Integer> largeList = ...
List<List<Integer>> output = ListUtils.partition(largeList, targetSize);
Odpowiedź dostarczona przez polygenelubricants dzieli tablicę na podstawie podanego rozmiaru. Szukałem kodu, który podzieli tablicę na określoną liczbę części. Oto modyfikacja, którą zrobiłem w kodzie:
public static <T>List<List<T>> chopIntoParts( final List<T> ls, final int iParts )
{
final List<List<T>> lsParts = new ArrayList<List<T>>();
final int iChunkSize = ls.size() / iParts;
int iLeftOver = ls.size() % iParts;
int iTake = iChunkSize;
for( int i = 0, iT = ls.size(); i < iT; i += iTake )
{
if( iLeftOver > 0 )
{
iLeftOver--;
iTake = iChunkSize + 1;
}
else
{
iTake = iChunkSize;
}
lsParts.add( new ArrayList<T>( ls.subList( i, Math.min( iT, i + iTake ) ) ) );
}
return lsParts;
}
Mam nadzieję, że to komuś pomoże.
To działa dla mnie
/**
* Returns List of the List argument passed to this function with size = chunkSize
*
* @param largeList input list to be portioned
* @param chunkSize maximum size of each partition
* @param <T> Generic type of the List
* @return A list of Lists which is portioned from the original list
*/
public static <T> List<List<T>> chunkList(List<T> list, int chunkSize) {
if (chunkSize <= 0) {
throw new IllegalArgumentException("Invalid chunk size: " + chunkSize);
}
List<List<T>> chunkList = new ArrayList<>(list.size() / chunkSize);
for (int i = 0; i < list.size(); i += chunkSize) {
chunkList.add(list.subList(i, i + chunkSize >= list.size() ? list.size()-1 : i + chunkSize));
}
return chunkList;
}
Np .:
List<Integer> stringList = new ArrayList<>();
stringList.add(0);
stringList.add(1);
stringList.add(2);
stringList.add(3);
stringList.add(4);
stringList.add(5);
stringList.add(6);
stringList.add(7);
stringList.add(8);
stringList.add(9);
List<List<Integer>> chunkList = getChunkList1(stringList, 2);
Możemy podzielić listę na podstawie wielkości lub warunku.
static Collection<List<Integer>> partitionIntegerListBasedOnSize(List<Integer> inputList, int size) {
return inputList.stream()
.collect(Collectors.groupingBy(s -> (s-1)/size))
.values();
}
static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList, int size) {
final AtomicInteger counter = new AtomicInteger(0);
return inputList.stream()
.collect(Collectors.groupingBy(s -> counter.getAndIncrement()/size))
.values();
}
static <T> Collection<List<T>> partitionBasedOnCondition(List<T> inputList, Predicate<T> condition) {
return inputList.stream().collect(Collectors.partitioningBy(s-> (condition.test(s)))).values();
}
Następnie możemy użyć ich jako:
final List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
System.out.println(partitionIntegerListBasedOnSize(list, 4)); // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
System.out.println(partitionBasedOnSize(list, 4)); // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
System.out.println(partitionBasedOnSize(list, 3)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
System.out.println(partitionBasedOnCondition(list, i -> i<6)); // [[6, 7, 8, 9, 10], [1, 2, 3, 4, 5]]
Zgaduję, że masz problem z nazwaniem 100 ArrayLists i zapełnieniem ich. Możesz utworzyć tablicę ArrayLists i wypełnić każdą z nich za pomocą pętli.
Najprostszym (najgłupszym) sposobem na zrobienie tego jest:
ArrayList results = new ArrayList(1000);
// populate results here
for (int i = 0; i < 1000; i++) {
results.add(i);
}
ArrayList[] resultGroups = new ArrayList[100];
// initialize all your small ArrayList groups
for (int i = 0; i < 100; i++) {
resultGroups[i] = new ArrayList();
}
// put your results into those arrays
for (int i = 0; i < 1000; i++) {
resultGroups[i/10].add(results.get(i));
}
Podobne pytanie zostało omówione tutaj, Java: podzielić Listę na dwie podlisty?
Głównie możesz użyć listy podrzędnej. Więcej informacji tutaj: subList
Zwraca widok części tej listy między fromIndex, włącznie, i toIndex, wyłączną. (Jeśli wartości fromIndex i toIndex są równe, zwrócona lista jest pusta). Zwrócona lista jest wspierana przez tę listę, więc zmiany na zwróconej liście są odzwierciedlane na tej liście i odwrotnie. Zwrócona lista obsługuje wszystkie opcjonalne operacje na liście obsługiwane przez tę listę ...
private ArrayList<List<String>> chunkArrayList(ArrayList<String> arrayToChunk, int chunkSize) {
ArrayList<List<String>> chunkList = new ArrayList<>();
int guide = arrayToChunk.size();
int index = 0;
int tale = chunkSize;
while (tale < arrayToChunk.size()){
chunkList.add(arrayToChunk.subList(index, tale));
guide = guide - chunkSize;
index = index + chunkSize;
tale = tale + chunkSize;
}
if (guide >0) {
chunkList.add(arrayToChunk.subList(index, index + guide));
}
Log.i("Chunked Array: " , chunkList.toString());
return chunkList;
}
Przykład
ArrayList<String> test = new ArrayList<>();
for (int i=1; i<=1000; i++){
test.add(String.valueOf(i));
}
chunkArrayList(test,10);
Wynik
CHUNKED :: [[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, 100], .........
zobaczysz w swoim dzienniku
Możesz użyć chunkmetody z kolekcji Eclipse :
ArrayList<Integer> list = new ArrayList<>(Interval.oneTo(1000));
RichIterable<RichIterable<Integer>> chunks = Iterate.chunk(list, 10);
Verify.assertSize(100, chunks);
Kilka przykładów tej chunkmetody zostało również zawartych w tym artykule DZone .
Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse.
Utwórz nową listę i dodaj widok listy źródłowej listy źródłowej za pomocą metody addAll, aby utworzyć nową
listę podrzędną List newList = new ArrayList (); newList.addAll (sourceList.subList (startIndex, endIndex));
Możesz także użyć biblioteki FunctionalJava - istnieje partitionmetoda List. Ta biblioteka ma swoje własne typy kolekcji, możesz konwertować je na kolekcje java tam iz powrotem.
import fj.data.List;
java.util.List<String> javaList = Arrays.asList("a", "b", "c", "d" );
List<String> fList = Java.<String>Collection_List().f(javaList);
List<List<String> partitions = fList.partition(2);
import org.apache.commons.collections4.ListUtils;
ArrayList<Integer> mainList = .............;
List<List<Integer>> multipleLists = ListUtils.partition(mainList,100);
int i=1;
for (List<Integer> indexedList : multipleLists){
System.out.println("Values in List "+i);
for (Integer value : indexedList)
System.out.println(value);
i++;
}
jeśli nie chcesz importować biblioteki apache commons, wypróbuj ten prosty kod:
final static int MAX_ELEMENT = 20;
public static void main(final String[] args) {
final List<String> list = new ArrayList<String>();
for (int i = 1; i <= 161; i++) {
list.add(String.valueOf(i));
System.out.print("," + String.valueOf(i));
}
System.out.println("");
System.out.println("### >>> ");
final List<List<String>> result = splitList(list, MAX_ELEMENT);
for (final List<String> entry : result) {
System.out.println("------------------------");
for (final String elm : entry) {
System.out.println(elm);
}
System.out.println("------------------------");
}
}
private static List<List<String>> splitList(final List<String> list, final int maxElement) {
final List<List<String>> result = new ArrayList<List<String>>();
final int div = list.size() / maxElement;
System.out.println(div);
for (int i = 0; i <= div; i++) {
final int startIndex = i * maxElement;
if (startIndex >= list.size()) {
return result;
}
final int endIndex = (i + 1) * maxElement;
if (endIndex < list.size()) {
result.add(list.subList(startIndex, endIndex));
} else {
result.add(list.subList(startIndex, list.size()));
}
}
return result;
}
Żeby było jasne, wciąż trzeba to przetestować więcej ...
public class Splitter {
public static <T> List<List<T>> splitList(List<T> listTobeSplit, int size) {
List<List<T>> sublists= new LinkedList<>();
if(listTobeSplit.size()>size) {
int counter=0;
boolean lastListadded=false;
List<T> subList=new LinkedList<>();
for(T t: listTobeSplit) {
if (counter==0) {
subList =new LinkedList<>();
subList.add(t);
counter++;
lastListadded=false;
}
else if(counter>0 && counter<size-1) {
subList.add(t);
counter++;
}
else {
lastListadded=true;
subList.add(t);
sublists.add(subList);
counter=0;
}
}
if(lastListadded==false)
sublists.add(subList);
}
else {
sublists.add(listTobeSplit);
}
log.debug("sublists: "+sublists);
return sublists;
}
}
**Divide a list to lists of n size**
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
public final class PartitionUtil<T> extends AbstractList<List<T>> {
private final List<T> list;
private final int chunkSize;
private PartitionUtil(List<T> list, int chunkSize) {
this.list = new ArrayList<>(list);
this.chunkSize = chunkSize;
}
public static <T> PartitionUtil<T> ofSize(List<T> list, int chunkSize) {
return new PartitionUtil<>(list, chunkSize);
}
@Override
public List<T> get(int index) {
int start = index * chunkSize;
int end = Math.min(start + chunkSize, list.size());
if (start > end) {
throw new IndexOutOfBoundsException("Index " + index + " is out of the list range <0," + (size() - 1) + ">");
}
return new ArrayList<>(list.subList(start, end));
}
@Override
public int size() {
return (int) Math.ceil((double) list.size() / (double) chunkSize);
}
}
Function call :
List<List<String>> containerNumChunks = PartitionUtil.ofSize(list, 999)
więcej szczegółów: https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/
Musisz znać wielkość porcji, przez którą dzielisz listę. Załóżmy, że masz listę 108 entriesi potrzebujesz rozmiaru fragmentu 25. W ten sposób skończysz z 5 lists:
25 entries każdy;8 elements.Kod:
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (int i=0; i<108; i++){
list.add(i);
}
int size= list.size();
int j=0;
List< List<Integer> > splittedList = new ArrayList<List<Integer>>() ;
List<Integer> tempList = new ArrayList<Integer>();
for(j=0;j<size;j++){
tempList.add(list.get(j));
if((j+1)%25==0){
// chunk of 25 created and clearing tempList
splittedList.add(tempList);
tempList = null;
//intializing it again for new chunk
tempList = new ArrayList<Integer>();
}
}
if(size%25!=0){
//adding the remaining enteries
splittedList.add(tempList);
}
for (int k=0;k<splittedList.size(); k++){
//(k+1) because we started from k=0
System.out.println("Chunk number: "+(k+1)+" has elements = "+splittedList.get(k).size());
}
}