Який найкращий спосіб видалити перший елемент із масиву?


86

У мене є масив рядків ( String[]), і мені потрібно видалити перший елемент. Як я можу зробити це ефективно?



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

32
Важливо зазначити, що видалення першого елемента з an ArrayListє O (n).
Matthew Flaschen

1
@Matt, для масиву та списку. Але код набагато простіший для списку.
jjnguy

16
Для масиву та an ArrayList, але не для LinkedList.
Matthew Flaschen

4
O (n)? ну .. у масиві C? щоб видалити елемент кулака, ви можете просто збільшити покажчик O (1)
Hernán Eche

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

4
Оскільки він використовує Java6, він може використовувати більш компактний Arrays.copyOfRange
Тіло

1
@Justin - точно, але лише якщо ви націлюєтесь на Java 1.6 або новішої
версії

1
правда. Це не завжди застосовується.
jjnguy

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), як тільки ви потрапите в ListIteratorце положення. Однак доступ до довільного елемента за індексом - O (n).


2

Зберігайте індекс першого "живого" елемента масиву. Видалення (вдавання видалення) першого елемента в подальшому стає O(1)операцією складності часу.


0

Підводячи підсумок, метод швидкого списку:

List<String> llist = new LinkedList<String>(Arrays.asList(oldArray));
llist.remove(0);

-8

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

   String[] a ={"BLAH00001","DIK-11","DIK-2","MAN5"};
   String[] k=Arrays.toString(a).split(", ",2)[1].split("]")[0].split(", ");

2
Будь ласка, хтось із достатньою репутацією підтримав цю відповідь - це саме те, що він каже, що це - негарно! Не майте наміру бути грубим, але в інтересах кодування, будь ласка, не публікуйте подібні речі!
Hack5

якщо ви вже використовуєте Arrays, було б краще використовувати Arrays.copyOfRange
Bishal Gautam

Він попросив найкращий спосіб.
Sapphire_Brick

видаліть його і подивіться, скільки репутації ви здобудете.
Sapphire_Brick
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.