web-dev-qa-db-fra.com

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 trouvé le moyen de redimensionner le tableau tout en conservant les éléments actuels.

J'ai trouvé par exemple un 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 une programmation dynamique, mais je ne sais pas comment l'implémenter.

42
Bujanca Mihai

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, à l'aide de Java.lang.System.arraycopy(...);.

  2. Utilisez la classe Java.util.ArrayList<T>, qui le fait pour vous lorsque vous devez agrandir le tableau. Cela résume bien ce que vous décrivez dans votre question.

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

79
Steve McLeod

Pas sympa, mais ça marche:

    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

19
jlordo

Voici deux 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 de longueur. Les composants situés aux positions srcPos via srcPos + longueur-1 dans le tableau source sont copiés dans les positions destPos via destPos + longueur-1, respectivement, du tableau de destination. 

Object[] originalArray = new Object[5];   
Object[] largerArray = new Object[10];
System.arraycopy(originalArray, 0, largerArray, 0, originalArray.length);

Méthode 2: Arrays.copyOf() :

Copie le tableau spécifié, le tronque ou le remplissage avec des valeurs NULL (si nécessaire) afin que la copie ait la longueur spécifiée. Pour tous les index valides dans le tableau d'origine et dans la copie, les deux tableaux contiendront des valeurs identiques. Pour tous les index valides dans la copie mais pas l'original, la copie contiendra null. De tels index existeront si et seulement si la longueur spécifiée est supérieure à celle du tableau d'origine. Le tableau résultant a exactement la même classe que le tableau d'origine.

Object[] originalArray = new Object[5];   
Object[] largerArray = Arrays.copyOf(originalArray, 10);

Notez que cette méthode utilise généralement System.arraycopy()en coulisse .


Méthode 3: ArrayList :

Implémentation de tableau redimensionnable de l'interface List. Implémente toutes les opérations de liste facultatives et autorise tous les éléments, y compris null. En plus d'implémenter l'interface List, 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, à l'exception du fait 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 un tableau , et utilise Arrays.copyOf .

ArrayList<Object> list = new ArrayList<>();

// This will add the element, resizing the ArrayList if necessary.
list.add(new Object());
11
Anubian Noob

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

5
Kirill Rakhman

Vous pouvez utiliser un ArrayList au lieu d'un tableau. Pour que vous puissiez ajouter n nombre d'éléments

 List<Integer> myVar = new ArrayList<Integer>();
2
Suranga

La classe standard Java.util.ArrayList est un tableau redimensionnable, croissant lorsque de nouveaux éléments sont ajoutés.

2

Vous ne pouvez pas redimensionner un tableau, mais vous pouvez le redéfinir en conservant les anciennes valeurs ou utiliser un fichier Java.util.List.

Voici deux solutions mais attrapez les différences de performances en utilisant 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: 201724266.
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
Codemix

Il n'est pas possible de changer la taille du tableau. Mais vous pouvez copier l’élément d’un tableau dans un autre en créant un tableau de plus grande taille. 

Il est recommandé de créer un tableau de taille double si Array est plein et de réduire le tableau à réduire de moitié si Array est rempli à moitié

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
Ranjeet Kumar

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
sreenath reddy

Désolé, mais pour le moment il n’est pas possible de redimensionner les tableaux et risque de ne jamais l’être.

Donc, ma recommandation est de penser plus pour trouver une solution qui vous permette d'obtenir, dès le début du processus, la taille des tableaux que vous aurez besoin Cela implique 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
Daniel De León

Il n'est pas possible de redimensionner un tableau. Cependant, il est possible de changer la taille d'un tableau en copiant le tableau d'origine dans le nouveau format 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
Lee