Ridimensiona una matrice mantenendo gli elementi correnti in Java?

Ho cercato un modo per ridimensionare un array in Java, ma non sono riuscito a trovare modi per ridimensionare l’array mantenendo gli elementi correnti .

Ho trovato per esempio il codice come int[] newImage = new int[newWidth]; , ma questo elimina gli elementi precedentemente memorizzati.

Il mio codice lo farebbe fondamentalmente: ogni volta che viene aggiunto un nuovo elemento, l’array viene ingrandito di 1 . Penso che questo potrebbe essere fatto con la programmazione dynamic, ma io sono, non sono sicuro di come implementarlo.

Non è ansible ridimensionare un array in Java. Avresti bisogno di:

  1. Creare una nuova matrice della dimensione desiderata e copiare il contenuto dalla matrice originale al nuovo array, usando java.lang.System.arraycopy(...);

  2. Usa la class java.util.ArrayList , che fa questo per te quando hai bisogno di ingrandire l’array. Incapsula perfettamente ciò che descrivi nella tua domanda.

  3. Utilizzare i metodi java.util.Arrays.copyOf(...) che restituisce un array più grande, con il contenuto dell’array originale.

Non bello, ma funziona:

  int[] a = {1, 2, 3}; // make a one bigger a = Arrays.copyOf(a, a.length + 1); for (int i : a) System.out.println(i); 

come detto prima, vai con ArrayList

Ecco un paio di modi per farlo.


Metodo 1: System.arrayCopy() :

Copia una matrice dall’array sorgente specificato, iniziando dalla posizione specificata, nella posizione specificata dell’array di destinazione. Una sottosequenza di componenti di matrice viene copiata dall’array di origine a cui fa riferimento src l’array di destinazione a cui fa riferimento dest. Il numero di componenti copiati è uguale all’argomento lunghezza. I componenti nelle posizioni srcPos tramite srcPos + length-1 nell’array sorgente vengono copiati in posizioni destPos tramite destPos + length-1, rispettivamente, dell’array di destinazione.

 Object[] arr = new Object[5]; // initialize elements Object[] largerArr = new Object[10]; System.arrayCopy(arr, 0, largerArr, 0, arr.length(); 

Metodo 2: Arrays.copyOf() :

Copia l’array specificato, troncando o riempendo di null (se necessario) in modo che la copia abbia la lunghezza specificata. Per tutti gli indici validi sia nell’array originale che nella copia, i due array conterranno valori identici. Per tutti gli indici che sono validi nella copia ma non nell’originale, la copia conterrà null. Tali indici esisteranno se e solo se la lunghezza specificata è maggiore di quella dell’array originale. L’array risultante è esattamente della stessa class dell’array originale.

 Object[] arr = new Object[5]; // initialize elements Object[] largerArr = Arrays.copyOf(arr, 10); 

Si noti che questo metodo solitamente utilizza System.arrayCopy() dietro le quinte .


Metodo 3: ArrayList :

Implementazione di array ridimensionabile dell’interfaccia List. Implementa tutte le operazioni di lista opzionali e consente tutti gli elementi, incluso il nulla. Oltre a implementare l’interfaccia Elenco, questa class fornisce metodi per manipolare le dimensioni dell’array utilizzato internamente per memorizzare l’elenco. (Questa class è approssimativamente equivalente a Vector, tranne che non è sincronizzata.)

ArrayList funziona in modo simile a un array, ma si espande automaticamente quando aggiungi più elementi di quanti ne possa contenere. È supportato da un array e utilizza Arrays.copyOf .

 ArrayList list = new ArrayList<>(); // initialize elements list.add(new Object()); // This will add the element, resizing the ArrayList if necassary. 

Potresti semplicemente usare ArrayList che fa il lavoro per te.

È ansible utilizzare un ArrayList anziché un array. In modo che tu possa aggiungere n numero di elementi

  List myVar = new ArrayList(); 

La class standard java.util.ArrayList è una matrice ridimensionabile, in crescita quando vengono aggiunti nuovi elementi.

Non è ansible modificare la dimensione dell’array. Ma puoi copiare l’elemento di un array in un altro array creando una matrice di dimensioni maggiori.

Si consiglia di creare array di doppia dimensione se l’array è pieno e ridurre la matrice per dimezzare se l’array è pieno a metà

 public class ResizingArrayStack1 { private String[] s; private int size = 0; private int index = 0; public void ResizingArrayStack1(int size) { this.size = size; s = new String[size]; } public void push(String element) { if (index == s.length) { resize(2 * s.length); } s[index] = element; index++; } private void resize(int capacity) { String[] copy = new String[capacity]; for (int i = 0; i < s.length; i++) { copy[i] = s[i]; s = copy; } } public static void main(String[] args) { ResizingArrayStack1 rs = new ResizingArrayStack1(); rs.push("a"); rs.push("b"); rs.push("c"); rs.push("d"); } } 

Non è ansible ridimensionare un array, ma è ansible ridefinirlo mantenendo vecchi valori o utilizzare un java.util.List

Qui seguono due soluzioni, ma rilevate le differenze di prestazioni che eseguono il codice seguente

Gli elenchi Java sono 450 volte più veloci ma 20 volte più pesanti in memoria!

 testAddByteToArray1 nanoAvg: 970355051 memAvg: 100000
 testAddByteToList1 nanoAvg: 1923106 memAvg: 2026856
 testAddByteToArray1 nanoAvg: 919582271 memAvg: 100000
 testAddByteToList1 nanoAvg: 1922660 memAvg: 2026856
 testAddByteToArray1 nanoAvg: 917727475 memAvg: 100000
 testAddByteToList1 nanoAvg: 1904896 memAvg: 2026856
 testAddByteToArray1 nanoAvg: 918483397 memAvg: 100000
 testAddByteToList1 nanoAvg: 1907243 memAvg: 2026856
 import java.util.ArrayList; import java.util.List; public class Test { public static byte[] byteArray = new byte[0]; public static List byteList = new ArrayList<>(); public static List nanoAvg = new ArrayList<>(); public static List memAvg = new ArrayList<>(); public static void addByteToArray1() { // >>> SOLUTION ONE < << byte[] a = new byte[byteArray.length + 1]; System.arraycopy(byteArray, 0, a, 0, byteArray.length); byteArray = a; //byteArray = Arrays.copyOf(byteArray, byteArray.length + 1); // the same as System.arraycopy() } public static void addByteToList1() { // >>> SOLUTION TWO < << byteList.add(new Byte((byte) 0)); } public static void testAddByteToList1() throws InterruptedException { System.gc(); long m1 = getMemory(); long n1 = System.nanoTime(); for (int i = 0; i < 100000; i++) { addByteToList1(); } long n2 = System.nanoTime(); System.gc(); long m2 = getMemory(); byteList = new ArrayList<>(); nanoAvg.add(new Double(n2 - n1)); memAvg.add(new Double(m2 - m1)); } public static void testAddByteToArray1() throws InterruptedException { System.gc(); long m1 = getMemory(); long n1 = System.nanoTime(); for (int i = 0; i < 100000; i++) { addByteToArray1(); } long n2 = System.nanoTime(); System.gc(); long m2 = getMemory(); byteArray = new byte[0]; nanoAvg.add(new Double(n2 - n1)); memAvg.add(new Double(m2 - m1)); } public static void resetMem() { nanoAvg = new ArrayList<>(); memAvg = new ArrayList<>(); } public static Double getAvg(List dl) { double max = Collections.max(dl); double min = Collections.min(dl); double avg = 0; boolean found = false; for (Double aDouble : dl) { if (aDouble < max && aDouble > min) { if (avg == 0) { avg = aDouble; } else { avg = (avg + aDouble) / 2d; } found = true; } } if (!found) { return getPopularElement(dl); } return avg; } public static double getPopularElement(List a) { int count = 1, tempCount; double popular = a.get(0); double temp = 0; for (int i = 0; i < (a.size() - 1); i++) { temp = a.get(i); tempCount = 0; for (int j = 1; j < a.size(); j++) { if (temp == a.get(j)) tempCount++; } if (tempCount > count) { popular = temp; count = tempCount; } } return popular; } public static void testCompare() throws InterruptedException { for (int j = 0; j < 4; j++) { for (int i = 0; i < 20; i++) { testAddByteToArray1(); } System.out.println("testAddByteToArray1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\tmemAvg:" + getAvg(memAvg).longValue()); resetMem(); for (int i = 0; i < 20; i++) { testAddByteToList1(); } System.out.println("testAddByteToList1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\t\tmemAvg:" + getAvg(memAvg).longValue()); resetMem(); } } private static long getMemory() { Runtime runtime = Runtime.getRuntime(); return runtime.totalMemory() - runtime.freeMemory(); } public static void main(String[] args) throws InterruptedException { testCompare(); } } 

Non è ansible ridimensionare un array. Tuttavia, è ansible modificare la dimensione di un array copiando l’array originale su quello appena dimensionato e mantenendo gli elementi correnti. La matrice può anche essere ridotta di dimensioni rimuovendo un elemento e ridimensionando.

 import java.util.Arrays public class ResizingArray { public static void main(String[] args) { String[] stringArray = new String[2] //A string array with 2 strings stringArray[0] = "string1"; stringArray[1] = "string2"; // increase size and add string to array by copying to a temporary array String[] tempStringArray = Arrays.copyOf(stringArray, stringArray.length + 1); // Add in the new string tempStringArray[2] = "string3"; // Copy temp array to original array stringArray = tempStringArray; // decrease size by removing certain string from array (string1 for example) for(int i = 0; i < stringArray.length; i++) { if(stringArray[i] == string1) { stringArray[i] = stringArray[stringArray.length - 1]; // This replaces the string to be removed with the last string in the array // When the array is resized by -1, The last string is removed // Which is why we copied the last string to the position of the string we wanted to remove String[] tempStringArray2 = Arrays.copyOf(arrayString, arrayString.length - 1); // Set the original array to the new array stringArray = tempStringArray2; } } } } 

Puoi provare sotto la soluzione all’interno di alcune classi:

 int[] a = {10, 20, 30, 40, 50, 61}; // private visibility - or change it as needed private void resizeArray(int newLength) { a = Arrays.copyOf(a, a.length + newLength); System.out.println("New length: " + a.length); }