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!
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. :)
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.
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.
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;
}
Vous devez créer manuellement un nouveau tableau plus grand et copier les éléments.
ceci peut aider
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) ...
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).
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