Як додати нові елементи до масиву?


291

У мене є такий код:

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

Ці два додатки не складаються. Як би це було правильно?

Відповіді:


395

Розмір масиву неможливо змінити. Якщо ви хочете отримати більший масив, вам доведеться створити новий.

Кращим рішенням буде використання виробу, ArrayListякий може рости у міру необхідності. Метод ArrayList.toArray( T[] a )повертає масив, якщо він вам потрібен у цій формі.

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

Якщо вам потрібно перетворити його в простий масив ...

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

Але більшість речей, які ви робите з масивом, ви також можете зробити з цим ArrayList:

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

// get specific items
where.get( 1 );

9
Який сенс у використанні Array, якщо ви можете зробити те ж саме з ArrayList?
Skoua

@ tangens.Я новачок в android, але ваша відповідь мені допомогла. Перш ніж знайти відповідь, я витратив багато годин
scott

1
@Skoua масиви ефективніші. Попереднє визначення розміру об'єкта дозволяє компілятору оптимізувати пам'ять. Для деяких додатків це має значення. Невеликий додаток, що працює на сучасному комп’ютері, можливо, може отримати багато списків, перш ніж пам'ять стане проблемою.
DraxDomax

102

Використовуйте List<String>, наприклад, ан ArrayList<String>. Це динамічно розростається, на відміну від масивів (див. Ефективне Java 2-е видання, Пункт 25: Переважно списки до масивів )

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

Якщо ви наполягаєте на використанні масивів, ви можете java.util.Arrays.copyOfвиділити більший масив для розміщення додаткового елемента. Це дійсно не найкраще рішення.

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

Це O(N)за пер append. ArrayListз іншого боку, має O(1)амортизовану вартість за операцію.

Дивитися також


Ви можете подвоїти розмір масиву щоразу, коли ємність недостатня. Таким чином додаток буде амортизовано O (1). Напевно, що ArrayListробить внутрішньо.
Сіюань Рен

32

Apache Commons Lang має

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

він повертає новий масив, але якщо ви дійсно працюєте з масивами з якихось причин, це може бути ідеальним способом зробити це.


23

Є ще один варіант, якого я тут не бачив і який не передбачає "складних" Об'єктів або Колекцій.

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

14

Немає методу append()на масивах. Натомість, як уже запропоновано, об'єкт List може обслуговувати потребу в динамічній вставці елементів, наприклад.

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

Або якщо ви дійсно прагнете використовувати масив:

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

але тоді це фіксований розмір, і ніяких елементів не можна додавати.


Так чи параметризований запит також приймає ArrayList як selectionArgs?
Скайнет

7

Як говорили тангенси, розмір масиву фіксований. Але спочатку потрібно інстанціювати, інакше це буде лише нульова посилання.

String[] where = new String[10];

Цей масив може містити лише 10 елементів. Таким чином, ви можете додати значення лише 10 разів. У своєму коді ви отримуєте доступ до нульової посилання. Ось чому це не працює. Щоб мати динамічно зростаючу колекцію, використовуйте ArrayList.


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

6

Я зробив цей код! Це працює як шарм!

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

Сподіваюся що вам це подобається!!


5

Потрібно скористатися списком колекцій. Ви не можете змінити розмірність масиву.


4

Якщо ви хочете зберігати свої дані в простому масиві, як це

String[] where = new String[10];

і ви хочете додати до нього деякі елементи, як числа, будь ласка, нам StringBuilder, що набагато ефективніше, ніж об'єднання рядків.

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

Це набагато кращий спосіб побудувати рядок і зберігати її у масиві "де".


4

Додавання нових елементів до масиву 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);

1
Ах, я бачу, ви використовували <code>тег, і це мало проблеми з загальними типами. Будь ласка, намагайтеся уникати цього тегу, оскільки ... він має проблеми, і вставте свій код 4 пробілами, щоб отримати правильне форматування. Я зробив це для вашого запитання :).
Том

4

Існує багато способів додати елемент до масиву. Ви можете використовувати temp Listдля управління елементом, а потім конвертувати його назад, Arrayабо ви можете використовувати java.util.Arrays.copyOfта комбінувати його з дженериками для кращих результатів.

Цей приклад покаже вам, як:

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

    return newArray;
}

Для використання цього методу просто потрібно назвати його так:

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

Якщо ви хочете об'єднати два масиви, ви можете змінити попередній метод на зразок цього:

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

Тепер ви можете назвати метод таким:

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

Як я вже згадував, ви також можете використовувати Listоб'єкти. Однак для його безпечного використання знадобиться трохи зламати:

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

Тепер ви можете назвати метод таким:

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

newArray[elements.length] = element;, ти мав на увазі newArray[elements.length - 1] = element;?
David Riccitelli

3

Я не такий досвід у Java, але мені завжди говорили, що масиви - це статичні структури, які мають заздалегідь заданий розмір. Ви повинні використовувати ArrayList або вектор або будь-яку іншу динамічну структуру.


2

ви можете створити arraylist і використовувати Collection.addAll()для перетворення рядкового масиву у свій масив



2

Якщо вам дійсно хочеться змінити розмір масиву, ви можете зробити щось подібне:

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]

1

Розмір масиву неможливо змінити. Якщо вам доведеться використовувати масив, ви можете використовувати:

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

0

Також можливо заздалегідь виділити достатньо великий об'єм пам'яті. Ось проста реалізація стека: програма повинна виводити 3 та 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]);
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.