Как лучше всего удалить первый элемент из массива?

86

У меня есть строковый массив ( String[]), и мне нужно удалить первый элемент. Как я могу сделать это эффективно?

NullVoxPopuli
источник
возможный дубликат Как удалить объекты из массива в java?
Макдауэлл,
4
Не обман. Предыдущий вопрос касается удаления элементов по значению; речь идет об удалении элемента по индексу.
james.garriss

Ответы:

154

Размер массивов в Java изменить нельзя. Итак, технически вы не можете удалить какие-либо элементы из массива.

Один из способов имитации удаления элемента из массива - создать новый меньший массив, а затем скопировать все элементы из исходного массива в новый меньший массив.

String[] yourArray = Arrays.copyOfRange(oldArr, 1, oldArr.length);

Однако я бы не предлагал описанный выше метод. Вам действительно стоит использовать List<String>. Списки позволяют добавлять и удалять элементы из любого индекса. Это будет выглядеть примерно так:

List<String> list = new ArrayList<String>(); // or LinkedList<String>();
list.add("Stuff");
// add lots of stuff
list.remove(0); // removes the first item
jjnguy
источник
32
Важно отметить, что удаление первого элемента an ArrayList- это O (n).
Мэтью Флашен,
1
@Matt, для массива и списка. Но код для списка намного проще.
jjnguy 08
16
Для массива и ArrayList, но не для LinkedList.
Мэтью Флашен
4
О (п)? ну .. в массиве C? чтобы удалить первый элемент, вы можете просто увеличить указатель O (1)
Эрнан Эче
2
Для тех, кто использует Java для Android, как я, Arrays.copyOfRange()предназначен для API9 +
Sdghasemi
14

Самый простой способ, вероятно, следующий: вам в основном нужно построить новый массив, который на один элемент меньше, а затем скопировать элементы, которые вы хотите сохранить, в правильные позиции.

int n=oldArray.length-1;
String[] newArray=new String[n];
System.arraycopy(oldArray,1,newArray,0,n);

Обратите внимание: если вы обнаружите, что часто выполняете такие операции, это может быть признаком того, что вы действительно должны использовать другой тип структуры данных, например связанный список. Создание нового массива каждый раз - это операция O (n), которая может стать дорогостоящей, если ваш массив большой. Связанный список даст вам O (1) удаление первого элемента.

Альтернативный вариант - вообще не удалять первый элемент, а просто увеличивать целое число, указывающее на первый используемый индекс. Пользователи массива должны будут учитывать это смещение, но это может быть эффективным подходом. Класс Java String фактически использует этот метод для внутренних целей при создании подстрок.

Микера
источник
4
Технически это не самый простой способ. Arrays.copyOfRange()является.
jjnguy 08
4
Поскольку он использует Java6, он может использовать более компактный Arrays.copyOfRange
Тило
1
@Justin - конечно, но только если вы нацеливаетесь на Java 1.6 или выше
mikera
1
правда. Это не всегда применимо.
jjnguy 08
6
название вопроса становится ясно , что ОП будет заинтересован в ответах на Java 1.6 и выше.
Stephen C
5

Вы вообще не можете этого сделать, не говоря уже о том, чтобы быстро. Массивы в Java имеют фиксированный размер. Вы можете сделать две вещи:

  1. Сдвиньте каждый элемент на один вверх, затем установите для последнего элемента значение null.
  2. Создайте новый массив, затем скопируйте его.

Вы можете использовать System.arraycopyдля любого из них. Оба они O (n), поскольку они копируют все, кроме 1 элемента.

Если вы будете часто удалять первый элемент, подумайте об использовании LinkedListвместо него. Вы можете использовать LinkedList.remove, что есть в Queueинтерфейсе, для удобства. С LinkedList, удаление первого элемента - O (1). Фактически, удаление любого элемента - это O (1), если у вас есть a ListIteratorв этой позиции. Однако доступ к произвольному элементу по индексу - O (n).

Мэтью Флашен
источник
2

Сохраните индекс первого «живого» элемента массива. Удаление (имитация удаления) первого элемента становится O(1)операцией временной сложности.

MSW
источник
0

Подводя итог, метод быстрого списка ссылок:

List<String> llist = new LinkedList<String>(Arrays.asList(oldArray));
llist.remove(0);
mjad-org
источник
-8

Альтернативный уродливый метод:

   String[] a ={"BLAH00001","DIK-11","DIK-2","MAN5"};
   String[] k=Arrays.toString(a).split(", ",2)[1].split("]")[0].split(", ");
Эмиль
источник
2
Пожалуйста, кто-нибудь с достаточной репутацией проголосует против этого ответа - это именно то, о чем говорится - уродливо! Не хочу показаться грубым, но в интересах кодирования, пожалуйста, не публикуйте подобные вещи!
Hack5
если вы уже используете массивы, было бы лучше использовать Arrays.copyOfRange
Бишал Гаутам,
Он спросил, как лучше всего.
Sapphire_Brick
удалите его и посмотрите, сколько репутации вы получите.
Sapphire_Brick