web-dev-qa-db-fra.com

Comment pouvons-nous allouer et développer dynamiquement un tableau?

Je travaille sur un projet, mais je ne peux utiliser aucune structure de données Java existante (c'est-à-dire ArraysList, arbres, etc.)

Je ne peux utiliser que des tableaux. Par conséquent, je dois mettre à jour dynamiquement un tableau avec une nouvelle mémoire.

Je lis un fichier texte et pré-alloue 100 pour la mémoire des tableaux:

   String [] wordList;
   int wordCount = 0;
   int occurrence = 1;
   int arraySize = 100;
   wordList = new String[arraySize];
   while ((strLine = br.readLine()) != null)   {
         // Store the content into an array
         Scanner s = new Scanner(strLine);
         while(s.hasNext()) {
           wordList[wordCount] = s.next();
           wordCount++;
         } 
   }

Maintenant, cela fonctionne très bien pour moins de 100 éléments de la liste. br.readline est le lecteur en mémoire tampon parcourant chaque ligne d'un fichier texte. Je l'ai puis stocke chaque mot dans la liste et puis incrémente mon index (wordCount).

Cependant, une fois que j'ai un fichier texte avec plus de 100 éléments, j'obtiens une erreur d'allocation.

Comment puis-je mettre à jour dynamiquement ce tableau (et ainsi réinventer la roue)?

Merci!

9
Zack Tanner

Vous pouvez faire quelque chose comme ça:

String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
int arrayGrowth = 50;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null)   {
     // Store the content into an array
     Scanner s = new Scanner(strLine);
     while(s.hasNext()) {
         if (wordList.length == wordCount) {
              // expand list
              wordList = Arrays.copyOf(wordList, wordList.length + arrayGrowth);
         }
         wordList[wordCount] = s.next();
         wordCount++;
     } 
}

Utiliser Java.util.Arrays.copyOf(String[]) fait fondamentalement la même chose que:

if (wordList.length == wordCount) {
    String[] temp = new String[wordList.length + arrayGrowth];
    System.arraycopy(wordList, 0, temp, 0, wordList.length);
    wordList = temp;
}

sauf que c'est une ligne de code au lieu de trois. :)

18
Ted Hopp

Vous allouez un nouveau tableau (le double de sa capacité, par exemple) et y déplacez tous les éléments.

En gros, vous devez vérifier si la wordCount est sur le point de frapper la wordList.size(), le cas échéant, créer un nouveau tableau avec une longueur deux fois plus longue que le précédent et y copier tous les éléments (créer une méthode auxiliaire), puis assigner wordList à votre nouveau tableau. 

Pour copier le contenu, vous pourriez utiliser System.arraycopy, mais je ne suis pas sûr que vos restrictions vous le permettent, vous pouvez donc simplement copier les éléments un par un:

public String[] createNewArray(String[] oldArray){
    String[] newArray = new String[oldArray.length * 2];
    for(int i = 0; i < oldArray.length; i++) {
        newArray[i] = oldArray[i];
    }

    return newArray;
}

Procéder.

5
pcalcao

Jetez un coup d'œil à l'implémentation de Java ArrayList . Java ArrayList utilise en interne un tableau de taille fixe et le réaffecte une fois que le nombre d'éléments dépasse la taille actuelle. Vous pouvez également mettre en œuvre sur des lignes similaires. 

3
MoveFast

vous ne pouvez pas augmenter la taille du tableau dynamiquement, mieux vous copiez dans la nouvelle array Utilisez System.arrayCopy pour cela, mieux que de copier chaque élément dans un nouveau tableau. Pour référence Pourquoi System.arraycopy est-il natif en Java? .

private static Object resizeArray (Object oldArray, int newSize) {
   int oldSize = Java.lang.reflect.Array.getLength(oldArray);
   Class elementType = oldArray.getClass().getComponentType();
   Object newArray = Java.lang.reflect.Array.newInstance(
         elementType, newSize);
   int preserveLength = Math.min(oldSize, newSize);
   if (preserveLength > 0)
      System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
   return newArray;
}
2
Subhrajyoti Majumder

Vous devez créer manuellement un nouveau tableau plus grand et copier les éléments.

ceci peut aider

0
Massimiliano Peluso

Visual Basic a une fonction Nice: ReDim Preserve.

Quelqu'un a bien voulu écrire une fonction équivalente - vous pouvez la trouver ici . Je pense que c'est exactement ce que vous demandez (et vous ne réinventez pas la roue - vous copiez celle de quelqu'un d'autre) ...

0
Floris

Prenons le cas où vous avez un tableau d'un élément et que vous souhaitez étendre la taille pour accueillir 1 million d'éléments de manière dynamique.

Cas 1:

String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 1];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

Cas 2 (taille augmentée d'un facteur d'addition):

String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 10];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

Cas 3 (taille augmentée d'un facteur de multiplication):

String [] wordList = new String[1];
String [] tmp = new String[wordList.length * 2];
for(int i = 0; i < wordList.length ; i++){
    tmp[i] = wordList[i];
}
wordList = tmp;

Lors de l'extension dynamique de la taille d'un tableau, de l'utilisation de Array.copy ou d'une itération sur le tableau et de la copie des éléments dans un nouveau tableau à l'aide de la boucle for, il effectue en réalité une itération sur chaque élément du tableau. C'est une opération coûteuse. Array.copy serait propre et optimisé, toujours coûteux. Donc, je suggérerais d'augmenter la longueur du tableau par un facteur de multiplication.

Comment ça aide est,

Dans le cas 1, pour prendre en charge 1 million d’éléments, vous devez augmenter la taille du tableau 1 million - 1 fois, soit 999 999 fois.

Dans le cas 2, vous devez augmenter la taille du tableau 1 million/10 - 1 fois, c'est-à-dire 99 999 fois.

Dans le cas 3, vous devez augmenter la taille du tableau par log21 million - 1 fois soit 18,9 (hypothétiquement).

0
Ashwin Aggarwal
public class Arr {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int a[] = {1,2,3};
        //let a[] is your original array
        System.out.println(a[0] + " " + a[1] + " " + a[2]);
        int b[];
        //let b[] is your temporary array with size greater than a[]
        //I have took 5
        b = new int[5];
        //now assign all a[] values to b[]
        for(int i = 0 ; i < a.length ; i ++)
            b[i] = a[i];
        //add next index values to b
        b[3] = 4;
        b[4] = 5;
        //now assign b[] to a[]
        a = b;
        //now you can heck that size of an original array increased
        System.out.println(a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " " 
    + a[4]);
    }

}

La sortie pour le code ci-dessus est:

1 2 3

1 2 3 4 5

0
Aitha Ranjeeth