Comment ajouter de nouveaux éléments à un tableau?

291

J'ai le code suivant:

String[] where;
where.append(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.append(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Ces deux ajouts ne sont pas en cours de compilation. Comment cela fonctionnerait-il correctement?

Pentium10
la source

Réponses:

395

La taille d'un tableau ne peut pas être modifiée. Si vous voulez un plus grand tableau, vous devez en instancier un nouveau.

Une meilleure solution serait d'utiliser un ArrayListqui peut se développer selon vos besoins. La méthode ArrayList.toArray( T[] a )vous rend votre tableau si vous en avez besoin sous cette forme.

List<String> where = new ArrayList<String>();
where.add( ContactsContract.Contacts.HAS_PHONE_NUMBER+"=1" );
where.add( ContactsContract.Contacts.IN_VISIBLE_GROUP+"=1" );

Si vous devez le convertir en un simple tableau ...

String[] simpleArray = new String[ where.size() ];
where.toArray( simpleArray );

Mais la plupart des choses que vous faites avec un tableau, vous pouvez aussi le faire avec cette ArrayList:

// iterate over the array
for( String oneItem : where ) {
    ...
}

// get specific items
where.get( 1 );
tangens
la source
9
Quel est l'intérêt d'utiliser Array si vous pouvez faire de même avec ArrayList?
Skoua
@ tangens.Je suis nouveau sur Android, mais votre réponse m'a aidé avant de trouver la réponse, j'ai perdu de nombreuses heures
Scott
1
Les tableaux @Skoua sont plus efficaces. Prédéfinir la taille de l'objet permet au compilateur d'optimiser la mémoire. Pour certaines applications, cela compte. Une petite application fonctionnant sur un ordinateur moderne peut probablement s'en tirer avec beaucoup de listes avant que la mémoire ne devienne un problème.
DraxDomax
102

Utilisez un List<String>, comme un ArrayList<String>. Il peut être développé dynamiquement, contrairement aux tableaux (voir: Effective Java 2nd Edition, Item 25: Prefer lists to arrays ).

import java.util.*;
//....

List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
System.out.println(list); // prints "[1, 2, 3]"

Si vous insistez pour utiliser des tableaux, vous pouvez utiliser java.util.Arrays.copyOfpour allouer un tableau plus grand pour accueillir l'élément supplémentaire. Ce n'est vraiment pas la meilleure solution, cependant.

static <T> T[] append(T[] arr, T element) {
    final int N = arr.length;
    arr = Arrays.copyOf(arr, N + 1);
    arr[N] = element;
    return arr;
}

String[] arr = { "1", "2", "3" };
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3]"
arr = append(arr, "4");
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3, 4]"

C'est O(N)par append. ArrayList, d'autre part, a O(1)amorti le coût par opération.

Voir également

polygénelubrifiants
la source
Vous pouvez doubler la taille de la baie chaque fois que la capacité n'est pas suffisante. De cette façon, l'ajout sera amorti O (1). Probablement ce que ArrayListfait en interne.
Siyuan Ren
32

Apache Commons Lang a

T[] t = ArrayUtils.add( initialArray, newitem );

il renvoie un nouveau tableau, mais si vous travaillez vraiment avec des tableaux pour une raison quelconque, cela peut être le moyen idéal de le faire.

xénoterracide
la source
23

Il y a une autre option que je n'ai pas vue ici et qui n'implique pas d'objets ou de collections "complexes".

String[] array1 = new String[]{"one", "two"};
String[] array2 = new String[]{"three"};
String[] array = new String[array1.length + array2.length];
System.arraycopy(array1, 0, array, 0, array1.length);
System.arraycopy(array2, 0, array, array1.length, array2.length);
ACLima
la source
14

Il n'y a pas de méthode append()sur les tableaux. Au lieu de cela, comme déjà suggéré, un objet List peut répondre au besoin d'insérer dynamiquement des éléments, par exemple.

List<String> where = new ArrayList<String>();
where.add(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.add(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Ou si vous souhaitez vraiment utiliser un tableau:

String[] where = new String[]{
    ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
    ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"
};

mais alors c'est une taille fixe et aucun élément ne peut être ajouté.

Robert
la source
Une requête paramétrée accepte-t-elle également ArrayList comme selectionArgs?
Skynet
7

Comme l'a dit tangens, la taille d'un tableau est fixe. Mais vous devez d'abord l'instancier, sinon ce ne sera qu'une référence nulle.

String[] where = new String[10];

Ce tableau ne peut contenir que 10 éléments. Vous ne pouvez donc ajouter une valeur que 10 fois. Dans votre code, vous accédez à une référence nulle. C'est pourquoi ça ne marche pas. Afin d'avoir une collection en croissance dynamique, utilisez ArrayList.

Simon
la source
7
String[] source = new String[] { "a", "b", "c", "d" };
String[] destination = new String[source.length + 2];
destination[0] = "/bin/sh";
destination[1] = "-c";
System.arraycopy(source, 0, destination, 2, source.length);

for (String parts : destination) {
  System.out.println(parts);
}
dforce
la source
6

J'ai fait ce code! Il fonctionne comme un charme!

public String[] AddToStringArray(String[] oldArray, String newString)
{
    String[] newArray = Arrays.copyOf(oldArray, oldArray.length+1);
    newArray[oldArray.length] = newString;
    return newArray;
}

J'espère que tu aimes!!

Ange
la source
5

Vous devez utiliser une liste de collection. Vous ne pouvez pas redimensionner un tableau.

Paligulus
la source
4

Si vous souhaitez stocker vos données dans un tableau simple comme celui-ci

String[] where = new String[10];

et vous voulez y ajouter des éléments comme des nombres, veuillez nous StringBuilder qui est beaucoup plus efficace que la concaténation de chaîne.

StringBuilder phoneNumber = new StringBuilder();
phoneNumber.append("1");
phoneNumber.append("2");
where[0] = phoneNumber.toString();

C'est une bien meilleure méthode pour construire votre chaîne et la stocker dans votre tableau 'where'.

RMachnik
la source
4

Ajout de nouveaux éléments au tableau String.

String[] myArray = new String[] {"x", "y"};

// Convert array to list
List<String> listFromArray = Arrays.asList(myArray);

// Create new list, because, List to Array always returns a fixed-size list backed by the specified array.
List<String> tempList = new ArrayList<String>(listFromArray);
tempList.add("z");

//Convert list back to array
String[] tempArray = new String[tempList.size()];
myArray = tempList.toArray(tempArray);
Kris
la source
1
Ah, je vois, vous avez utilisé la <code>balise et cela a eu des problèmes avec les types génériques. S'il vous plaît essayez d'éviter cette balise, car ... il a des problèmes, et indentez votre code avec 4 espaces blancs pour obtenir la mise en forme appropriée. Je l'ai fait pour votre question :).
Tom
4

Il existe de nombreuses façons d'ajouter un élément à un tableau. Vous pouvez utiliser un temp Listpour gérer l'élément, puis le reconvertir en Arrayou vous pouvez utiliser le java.util.Arrays.copyOfet le combiner avec des génériques pour de meilleurs résultats.

Cet exemple vous montrera comment:

public static <T> T[] append2Array(T[] elements, T element)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + 1);
    newArray[elements.length] = element;

    return newArray;
}

Pour utiliser cette méthode, il vous suffit de l'appeler comme ceci:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, "four");
System.out.println(Arrays.toString(numbers));

Si vous souhaitez fusionner deux tableaux, vous pouvez modifier la méthode précédente comme ceci:

public static <T> T[] append2Array(T[] elements, T[] newElements)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + newElements.length);
    System.arraycopy(newElements, 0, newArray, elements.length, newElements.length);

    return newArray;
}

Vous pouvez maintenant appeler la méthode comme ceci:

String[] numbers = new String[]{"one", "two", "three"};
String[] moreNumbers = new String[]{"four", "five", "six"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, moreNumbers);
System.out.println(Arrays.toString(numbers));

Comme je l'ai mentionné, vous pouvez également utiliser des Listobjets. Cependant, il faudra un petit hack pour le sécuriser comme ceci:

public static <T> T[] append2Array(Class<T[]> clazz, List<T> elements, T element)
{
    elements.add(element);
    return clazz.cast(elements.toArray());
}

Vous pouvez maintenant appeler la méthode comme ceci:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(String[].class, Arrays.asList(numbers), "four");
System.out.println(Arrays.toString(numbers));
Teocci
la source
newArray[elements.length] = element;, tu veux dire newArray[elements.length - 1] = element;?
David Riccitelli
3

Je ne suis pas très expérimenté en Java, mais on m'a toujours dit que les tableaux sont des structures statiques qui ont une taille prédéfinie. Vous devez utiliser une ArrayList ou un Vector ou toute autre structure dynamique.

npinti
la source
2

vous pouvez créer une liste de tableaux et l'utiliser Collection.addAll()pour convertir le tableau de chaînes en liste de tableaux

ratzip
la source
2

Vous pouvez simplement faire ceci:

System.arraycopy(initialArray, 0, newArray, 0, initialArray.length);
Jason Ivey
la source
2

Si l'on veut vraiment redimensionner un tableau, vous pouvez faire quelque chose comme ceci:

String[] arr = {"a", "b", "c"};
System.out.println(Arrays.toString(arr)); 
// Output is: [a, b, c]

arr = Arrays.copyOf(arr, 10); // new size will be 10 elements
arr[3] = "d";
arr[4] = "e";
arr[5] = "f";

System.out.println(Arrays.toString(arr));
// Output is: [a, b, c, d, e, f, null, null, null, null]
Au four
la source
1

La taille du tableau ne peut pas être modifiée. Si vous devez utiliser un tableau, vous pouvez utiliser:

System.arraycopy(src, srcpos, dest, destpos, length); 
Jiao
la source
0

Il est également possible de pré-allouer une taille de mémoire suffisamment grande. Voici une implémentation de pile simple: le programme est censé produire les sorties 3 et 5.

class Stk {
    static public final int STKSIZ = 256;
    public int[] info = new int[STKSIZ];
    public int sp = 0; // stack pointer
    public void push(int value) {
        info[sp++] = value;
    }
}
class App {
    public static void main(String[] args) {
        Stk stk = new Stk();
        stk.push(3);
        stk.push(5);
        System.out.println(stk.info[0]);
        System.out.println(stk.info[1]);
    }
}
baz
la source