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.

Author: DukeSpontaneous, 2012-11-02

11 answers

Vous ne pouvez pas redimensionner un tableau en Java. Vous devez soit:

  1. 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(...);

  2. 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.

  3. Utilisez des méthodes java.util.Arrays.copyOf(...) qui renvoient un tableau plus grand, avec le contenu du tableau d'origine.

 74
Author: Steve McLeod, 2012-11-02 15:03:47

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

 18
Author: jlordo, 2012-11-02 15:02:26

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.
 8
Author: Anubian Noob, 2015-09-04 18:05:16

Vous pouvez simplement utiliser ArrayList, qui fait le travail pour vous.

 5
Author: Kirill Rakhman, 2012-11-02 15:05:02

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>();
 2
Author: Suranga, 2012-11-02 14:59:44

Classe standard java.util.ArrayList est un tableau redimensionnable, croissant lorsque de nouveaux éléments sont ajoutés.

 2
Author: Alexei Kaigorodov, 2012-11-02 14:59:52

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");
    }
}
 1
Author: Ranjeet Kumar, 2017-10-15 21:59:58

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();
    }
}
 1
Author: Codemix, 2018-02-01 12:19:24

, 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;
           }
       }
    }    
}
 0
Author: Lee, 2016-07-29 23:21:11

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);
}
 0
Author: sreenath reddy, 2018-07-06 06:38:08

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.

 0
Author: Daniel De León, 2018-10-03 20:20:22