Cambiar el tamaño de una matriz mientras mantiene los elementos actuales en Java?

He buscado una manera de cambiar el tamaño de una matriz en Java, pero no pude encontrar formas de cambiar el tamaño de la matriz manteniendo los elementos actuales .

Encontré, por ejemplo, código como int[] newImage = new int[newWidth]; , pero esto elimina los elementos almacenados antes.

Mi código básicamente haría esto: cada vez que se agrega un nuevo elemento, la matriz se amplía en 1 . Creo que esto podría hacerse con progtwigción dinámica, pero estoy, no estoy seguro de cómo implementarlo.

No puede cambiar el tamaño de una matriz en Java. Necesitarías:

  1. Cree una nueva matriz del tamaño deseado y copie los contenidos de la matriz original a la nueva matriz, utilizando java.lang.System.arraycopy(...);

  2. Use la clase java.util.ArrayList , que hace esto por usted cuando necesita agrandar la matriz. Encapsula muy bien lo que describes en tu pregunta.

  3. Utilice los métodos java.util.Arrays.copyOf(...) que devuelve una matriz más grande, con los contenidos de la matriz original.

No es lindo, pero funciona:

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

como se dijo antes, ve con ArrayList

Aquí hay un par de maneras de hacerlo.


Método 1: System.arrayCopy() :

Copia una matriz de la matriz fuente especificada, comenzando en la posición especificada, a la posición especificada de la matriz de destino. Se copia una subsecuencia de componentes de matriz desde la matriz fuente referenciada por src a la matriz de destino referenciada por dest. La cantidad de componentes copiados es igual al argumento de longitud. Los componentes en las posiciones srcPos a través de srcPos + length-1 en la matriz fuente se copian en las posiciones destPos a través de destPos + length-1, respectivamente, de la matriz de destino.

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

Método 2: Arrays.copyOf() :

Copia la matriz especificada, truncando o rellenando con nulos (si es necesario) para que la copia tenga la longitud especificada. Para todos los índices que son válidos tanto en la matriz original como en la copia, las dos matrices contendrán valores idénticos. Para cualquier índice que sea válido en la copia pero no en el original, la copia contendrá nulo. Dichos índices existirán si y solo si la longitud especificada es mayor que la de la matriz original. La matriz resultante es exactamente de la misma clase que la matriz original.

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

Tenga en cuenta que este método generalmente usa System.arrayCopy() detrás de las escenas .


Método 3: ArrayList :

Implementación de arreglos redimensionables de la interfaz de la Lista. Implementa todas las operaciones de lista opcionales y permite todos los elementos, incluido el nulo. Además de implementar la interfaz de lista, esta clase proporciona métodos para manipular el tamaño de la matriz que se usa internamente para almacenar la lista. (Esta clase es más o menos equivalente a Vector, excepto que no está sincronizada).

ArrayList funciona de manera similar a una matriz, excepto que se expande automáticamente cuando agrega más elementos de los que puede contener. Está respaldado por una matriz y usa Arrays.copyOf .

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

Puede usar ArrayList que hace el trabajo por usted.

Puede usar una ArrayList en lugar de una matriz. Para que pueda agregar n cantidad de elementos

  List myVar = new ArrayList(); 

La clase estándar java.util.ArrayList es una matriz de tamaño variable, que crece cuando se agregan nuevos elementos.

No es posible cambiar el tamaño de la matriz. Pero puede copiar el elemento de una matriz en otra matriz creando una matriz de mayor tamaño.

Se recomienda crear una matriz de tamaño doble si la matriz está llena y reducir la matriz a la mitad si la matriz está medio llena

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

No puede cambiar el tamaño de una matriz, pero puede redefinirla manteniendo los valores anteriores o usar una java.util.List

A continuación, se presentan dos soluciones, pero se detectan las diferencias de rendimiento con el siguiente código

¡Las listas de Java son 450 veces más rápidas pero 20 veces más pesadas en la 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(); } } 

No es posible cambiar el tamaño de una matriz. Sin embargo, es posible cambiar el tamaño de una matriz mediante la copia de la matriz original a la nueva dimensión y mantener los elementos actuales. La matriz también se puede reducir de tamaño al eliminar un elemento y cambiar el tamaño.

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

Puedes probar la siguiente solución dentro de alguna clase:

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