Como adicionar novos elementos a uma matriz?

291

Eu tenho o seguinte código:

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

Esses dois anexos não estão sendo compilados. Como isso funcionaria corretamente?

Pentium10
fonte

Respostas:

395

O tamanho de uma matriz não pode ser modificado. Se você quer uma matriz maior, precisa instanciar uma nova.

Uma solução melhor seria usar um ArrayListque possa crescer conforme você precisar. O método ArrayList.toArray( T[] a )devolve sua matriz, se você precisar desta forma.

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

Se você precisar convertê-lo em uma matriz simples ...

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

Mas a maioria das coisas que você faz com uma matriz também pode fazer com este ArrayList:

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

// get specific items
where.get( 1 );
tangens
fonte
9
Qual é o sentido de usar Array se você pode fazer o mesmo com ArrayList?
Skoua
@ tangens.I sou novo para o Android, mas a sua resposta ajudou resposta me.before constatação i desperdiçou muitas horas
scott
1
As matrizes @Skoua são mais eficientes. A pré-definição do tamanho do objeto permite que o compilador otimize a memória. Para algumas aplicações, isso importa. Um pequeno aplicativo em execução em um computador moderno provavelmente pode acabar com muitas listas antes que a memória se torne um problema.
DraxDomax
102

Use a List<String>, como um ArrayList<String>. É dinamicamente expansível, ao contrário de matrizes (consulte: Java efetivo 2ª edição, item 25: Preferir listas para matrizes ).

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]"

Se você insistir em usar matrizes, poderá usar java.util.Arrays.copyOfpara alocar uma matriz maior para acomodar o elemento adicional. Esta realmente não é a melhor solução, no entanto.

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]"

Isso é O(N)por append. ArrayListpor outro lado, temO(1) amortizou o custo por operação.

Veja também

poligenelubricants
fonte
Você pode dobrar o tamanho da matriz sempre que a capacidade não for suficiente. Dessa forma, o anexo será amortizado O (1). Provavelmente o que ArrayListfaz internamente.
Siyuan Ren
32

O Apache Commons Lang possui

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

retorna uma nova matriz, mas se você realmente estiver trabalhando com matrizes por algum motivo, talvez seja a maneira ideal de fazer isso.

xenoterracida
fonte
23

Há outra opção que eu não vi aqui e que não envolve objetos ou coleções "complexos".

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
fonte
14

Não há método append()nas matrizes. Em vez disso, como já sugerido, um objeto List pode atender à necessidade de inserir elementos dinamicamente, por exemplo.

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

Ou se você está realmente interessado em usar uma matriz:

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

mas esse é um tamanho fixo e nenhum elemento pode ser adicionado.

Robert
fonte
Então, uma consulta parametrizada também aceita ArrayList como selectionArgs?
Skynet
7

Como tangens disse, o tamanho de uma matriz é fixo. Mas você deve instanciar primeiro, caso contrário, será apenas uma referência nula.

String[] where = new String[10];

Essa matriz pode conter apenas 10 elementos. Portanto, você pode acrescentar um valor apenas 10 vezes. No seu código, você está acessando uma referência nula. É por isso que não funciona. Para ter uma coleção crescente dinamicamente, use o ArrayList.

Simon
fonte
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);
}
força
fonte
6

Eu fiz esse código! Ele funciona como um encanto!

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

Espero que você goste!!

Anjo
fonte
5

Você precisa usar uma lista de coleções. Você não pode redimensionar uma matriz.

Paligulus
fonte
4

Se você deseja armazenar seus dados em um array simples como este

String[] where = new String[10];

e você deseja adicionar alguns elementos, como números, por favor, StringBuilder, que é muito mais eficiente do que concatenar string.

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

Este é um método muito melhor para construir sua string e armazená-la em seu array 'where'.

RMachnik
fonte
4

Adicionando novos itens ao array 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
fonte
1
Ah, entendo, você usou a <code>tag e isso teve problemas com os tipos genéricos. Tente evitar essa tag, pois ... ela tem problemas e indente seu código com 4 espaços em branco para obter a formatação correta. Eu fiz isso para sua pergunta :).
Tom
4

Existem várias maneiras de adicionar um elemento a uma matriz. Você pode usar um temp Listpara gerenciar o elemento e, em seguida, convertê-lo novamente Arrayou pode usá- java.util.Arrays.copyOflo e combiná-lo com genéricos para obter melhores resultados.

Este exemplo mostra como:

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

    return newArray;
}

Para usar esse método, basta chamá-lo assim:

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

Se você deseja mesclar duas matrizes, pode modificar o método anterior como este:

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;
}

Agora você pode chamar o método assim:

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));

Como eu mencionei, você também pode usar Listobjetos. No entanto, será necessário um pequeno hack para torná-lo seguro assim:

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

Agora você pode chamar o método assim:

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
fonte
newArray[elements.length] = element;, você quis dizer newArray[elements.length - 1] = element;?
David Riccitelli
3

Eu não sou tão experiente em Java, mas sempre me disseram que matrizes são estruturas estáticas que têm um tamanho predefinido. Você precisa usar um ArrayList ou um vetor ou qualquer outra estrutura dinâmica.

npinti
fonte
2

você pode criar uma lista de matrizes e usar Collection.addAll()para converter a matriz de cadeias de caracteres em sua lista de matrizes

ratzip
fonte
2

Você pode simplesmente fazer isso:

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

Se alguém realmente deseja redimensionar uma matriz, você pode fazer algo assim:

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]
Inhalf assado
fonte
1

O tamanho da matriz não pode ser modificado. Se você precisar usar uma matriz, poderá usar:

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

Também é possível pré-alocar tamanho de memória grande o suficiente. Aqui está uma implementação simples da pilha: o programa deve produzir 3 e 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
fonte