Redimensionner un tableau tout en conservant les éléments actuels en Java?
J'ai cherché un moyen de redimensionner un tableau en Java, mais je n'ai pas pu trouver de moyens de redimensionner le tableau tout en conservant les éléments actuels.
J'ai trouvé par exemple du code comme int[] newImage = new int[newWidth];
, mais cela supprime les éléments stockés auparavant.
Mon code ferait essentiellement ceci: chaque fois qu'un nouvel élément est ajouté, le tableau largens par 1. Je pense que cela pourrait être fait avec la programmation dynamique, mais je ne sais pas comment l'implémenter.
11 answers
Vous ne pouvez pas redimensionner un tableau en Java. Vous devez soit:
Créez un nouveau tableau de la taille souhaitée et copiez le contenu du tableau d'origine dans le nouveau tableau, en utilisant
java.lang.System.arraycopy(...);
Utilisez la classe
java.util.ArrayList<T>
, qui le fait pour vous lorsque vous devez agrandir le tableau. Il encapsule bien ce que vous décrivez dans votre question.Utilisez des méthodes
java.util.Arrays.copyOf(...)
qui renvoient un tableau plus grand, avec le contenu du tableau d'origine.
Pas gentil, mais fonctionne:
int[] a = {1, 2, 3};
// make a one bigger
a = Arrays.copyOf(a, a.length + 1);
for (int i : a)
System.out.println(i);
Comme indiqué précédemment, allez avec ArrayList
Voici quelques façons de le faire.
Méthode 1: System.arrayCopy()
:
Copie un tableau du tableau source spécifié, commençant à la position spécifiée, vers la position spécifiée du tableau de destination. Une sous-séquence de composants de tableau est copiée du tableau source référencé par src vers le tableau de destination référencé par dest. Le nombre de composants copiés est égal à l'argument length. Les composants aux positions srcPos par srcPos + length - 1 dans le tableau source sont copiés dans les positions destPos par destPos+length-1, respectivement, du tableau de destination.
Object[] arr = new Object[5];
// initialize elements
Object[] largerArr = new Object[10];
System.arrayCopy(arr, 0, largerArr, 0, arr.length();
Méthode 2: Arrays.copyOf()
:
Copie le tableau spécifié, en tronquant ou en remplissant avec des valeurs nulles (si nécessaire) afin que la copie ait la longueur spécifiée. Pour tous les indices valides à la fois dans le tableau d'origine et dans la copie, les deux tableaux contiendront des valeurs identiques. Pour tous les indices qui sont valides dans la copie mais pas l'original, la copie contiendra null. De tels indices existeront si et seulement si la longueur spécifiée est supérieure à celle du tableau d'origine. Le tableau résultant est exactement de la même classe que le tableau d'origine.
Object[] arr = new Object[5];
// initialize elements
Object[] largerArr = Arrays.copyOf(arr, 10);
Notez que cette méthode utilise habituellement System.arrayCopy()
derrière les scènes.
Méthode 3: ArrayList
:
Redimensionnable-implémentation de tableau de l'interface de liste. Implémente toutes les opérations de liste facultatives et autorise les éléments, y compris la valeur null. En plus d'implémenter l'interface de liste, cette classe fournit des méthodes pour manipuler la taille du tableau utilisé en interne pour stocker la liste. (Cette classe est à peu près équivalente à Vector, sauf qu'elle n'est pas synchronisée.)
ArrayList fonctionne de la même manière qu'un tableau, sauf qu'il se développe automatiquement lorsque vous ajoutez plus d'éléments qu'il ne peut en contenir. C'est soutenu par une matrice, et utilise des Tableaux.copyOf .
ArrayList<Object> list = new ArrayList<>();
// initialize elements
list.add(new Object());
// This will add the element, resizing the ArrayList if necassary.
Vous pouvez simplement utiliser ArrayList
, qui fait le travail pour vous.
Vous pouvez utiliser une ArrayList au lieu de array. Pour que vous puissiez ajouter n nombre d'éléments
List<Integer> myVar = new ArrayList<Integer>();
Classe standard java.util.ArrayList est un tableau redimensionnable, croissant lorsque de nouveaux éléments sont ajoutés.
Il n'est pas possible de modifier la taille du tableau. Mais vous pouvez copier l'élément d'un tableau dans un autre tableau en créant un tableau de plus grande taille.
Il est recommandé de créer un tableau de taille double si le tableau est plein et de le réduire de moitié si le tableau est à moitié plein
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");
}
}
Vous ne pouvez pas redimensionner un tableau, mais vous pouvez le redéfinir en gardant les anciennes valeurs ou en utilisant un java.util.Liste
Voici deux solutions mais attrapez les différences de performances en exécutant le code ci-dessous
Les listes Java sont 450 fois plus rapides mais 20 fois plus lourdes en mémoire!
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<Byte> byteList = new ArrayList<>();
public static List<Double> nanoAvg = new ArrayList<>();
public static List<Double> 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<Double> 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<Double> 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();
}
}
, Il n'est pas possible de redimensionner un tableau. Cependant, il est possible de modifier la taille d'un tableau en copiant le tableau d'origine vers le tableau nouvellement dimensionné et en conservant les éléments actuels. La taille du tableau peut également être réduite en supprimant un élément et en le redimensionnant.
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;
}
}
}
}
Vous pouvez essayer la solution ci-dessous dans une classe:
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);
}
Désolé, mais pour le moment, il n'est pas possible de redimensionner les tableaux, et peut-être ne le sera jamais.
Donc ma recommandation, est de penser plus pour trouver une solution qui vous permet d'obtenir dès le début du processus, la taille des tableaux que vous aurez besoin. Cela impliquera souvent que votre code a besoin d'un peu plus de temps (lignes) pour s'exécuter, mais vous économiserez beaucoup de ressources mémoire.