Jak dodać nowe elementy do tablicy?

291

Mam następujący kod:

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

Te dwa załączniki się nie kompilują. Jak to działałoby poprawnie?

Pentium10
źródło

Odpowiedzi:

395

Rozmiar tablicy nie może być modyfikowany. Jeśli chcesz mieć większą tablicę, musisz utworzyć nową.

Lepszym rozwiązaniem byłoby użycie takiego, ArrayListktóry może rosnąć w miarę potrzeb. Ta metoda ArrayList.toArray( T[] a )zwraca tablicę, jeśli jest potrzebna w tej formie.

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

Jeśli chcesz przekonwertować go na prostą tablicę ...

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

Ale większość rzeczy, które robisz z tablicą, możesz także zrobić za pomocą tej ArrayList:

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

// get specific items
where.get( 1 );
tangens
źródło
9
Po co używać Array, jeśli możesz zrobić to samo z ArrayList?
Skoua
@ tangens. Jestem nowy na Androida, ale twoja odpowiedź pomogła mi. zanim znalazłem odpowiedź, zmarnowałem wiele godzin
Scott
1
Tablice @Skoua są bardziej wydajne. Wstępne zdefiniowanie rozmiaru obiektu pozwala kompilatorowi zoptymalizować pamięć. W przypadku niektórych aplikacji ma to znaczenie. Mała aplikacja działająca na nowoczesnym komputerze może prawdopodobnie uciec od wielu list, zanim pamięć stanie się problemem.
DraxDomax,
102

Użyj a List<String>, np ArrayList<String>. Jest dynamicznie rozwijalny, w przeciwieństwie do tablic (patrz: Efektywna Java 2. edycja, pozycja 25: Preferuj listy od tablic ).

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

Jeśli nalegasz na użycie tablic, możesz użyć java.util.Arrays.copyOfdo przydzielenia większej tablicy, aby pomieścić dodatkowy element. To jednak nie jest najlepsze rozwiązanie.

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

To jest O(N)na append. ArrayList, z drugiej strony, O(1)zamortyzował koszt na operację.

Zobacz też

środki smarujące wielotlenowe
źródło
Możesz podwoić rozmiar tablicy za każdym razem, gdy pojemność jest niewystarczająca. W ten sposób dodatek zostanie zamortyzowany O (1). Prawdopodobnie to, co ArrayListrobi wewnętrznie.
Siyuan Ren
32

Apache Commons Lang ma

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

zwraca nową tablicę, ale jeśli z jakiegoś powodu naprawdę pracujesz z tablicami, może to być idealny sposób na zrobienie tego.

ksenoterracid
źródło
23

Jest jeszcze jedna opcja, której nie widziałem tutaj i która nie obejmuje „złożonych” obiektów lub kolekcji.

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
źródło
14

Nie ma metody append()na tablice. Zamiast tego, jak już sugerowano, obiekt List może obsłużyć potrzebę dynamicznego wstawiania elementów, np.

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

Lub jeśli naprawdę chcesz użyć tablicy:

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

ale wtedy jest to stały rozmiar i nie można dodawać żadnych elementów.

Robert
źródło
Czy więc sparametryzowane zapytanie akceptuje również ArrayList jako selectionArgs?
Skynet
7

Jak powiedziano tangens, rozmiar tablicy jest stały. Ale najpierw musisz go utworzyć, w przeciwnym razie będzie to tylko odwołanie zerowe.

String[] where = new String[10];

Ta tablica może zawierać tylko 10 elementów. Możesz więc dodać wartość tylko 10 razy. W swoim kodzie masz dostęp do pustego odwołania. Dlatego to nie działa. Aby mieć dynamicznie rosnącą kolekcję, użyj ArrayList.

Szymon
źródło
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);
}
zmusić
źródło
6

Zrobiłem ten kod! To działa jak urok!

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

Mam nadzieję, że to lubisz!!

Anioł
źródło
5

Musisz użyć listy kolekcji. Nie można ponownie zwymiarować tablicy.

Paligulus
źródło
4

Jeśli chcesz przechowywać swoje dane w prostej tablicy, takiej jak ta

String[] where = new String[10];

i chcesz dodać do niego niektóre elementy, takie jak liczby, prosimy o StringBuilder, który jest znacznie bardziej wydajny niż łączenie łańcucha.

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

Jest to znacznie lepsza metoda budowania łańcucha i przechowywania go w tablicy „gdzie”.

RMachnik
źródło
4

Dodanie nowych elementów do tablicy 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
źródło
1
Ach, rozumiem, użyłeś <code>tagu i to miało problemy z typami rodzajowymi. Staraj się unikać tego znacznika, ponieważ ... ma on problemy i wcinasz swój kod za pomocą 4 białych spacji, aby uzyskać odpowiednie formatowanie. Zrobiłem to dla twojego pytania :).
Tom
4

Istnieje wiele sposobów dodawania elementu do tablicy. Możesz użyć temp Listdo zarządzania elementem, a następnie przekonwertować go z powrotem Arraylub możesz użyć java.util.Arrays.copyOfi połączyć go z ogólnymi, aby uzyskać lepsze wyniki.

Ten przykład pokazuje, jak:

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

    return newArray;
}

Aby użyć tej metody, wystarczy wywołać ją w następujący sposób:

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

Jeśli chcesz scalić dwie tablice, możesz zmodyfikować poprzednią metodę w następujący sposób:

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

Teraz możesz wywołać metodę w ten sposób:

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

Jak wspomniałem, możesz także używać Listprzedmiotów. Jednak będzie to wymagało niewielkiego włamania, aby zapewnić bezpieczne:

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

Teraz możesz wywołać metodę w ten sposób:

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
źródło
newArray[elements.length] = element;miałeś na myśli newArray[elements.length - 1] = element;?
David Riccitelli,
3

Nie mam doświadczenia w Javie, ale zawsze mówiono mi, że tablice są strukturami statycznymi o z góry określonym rozmiarze. Musisz użyć ArrayList lub Vector lub innej dynamicznej struktury.

npinti
źródło
2

możesz utworzyć listę arraylist i użyć Collection.addAll()do przekonwertowania tablicy ciągów na listę arraylist

ratzip
źródło
2

Możesz po prostu to zrobić:

System.arraycopy(initialArray, 0, newArray, 0, initialArray.length);
Jason Ivey
źródło
2

Jeśli naprawdę chcesz zmienić rozmiar tablicy, możesz zrobić coś takiego:

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]
Pieczone Inhalf
źródło
1

Rozmiar tablicy nie może być modyfikowany. Jeśli musisz użyć tablicy, możesz użyć:

System.arraycopy(src, srcpos, dest, destpos, length); 
Jiao
źródło
0

Możliwe jest również wstępne przydzielenie wystarczającej ilości pamięci. Oto prosta implementacja stosu: program ma wypisywać 3 i 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
źródło