Cách tốt nhất để xóa phần tử đầu tiên khỏi mảng là gì?


86

Tôi có mảng chuỗi ( String[]) và tôi cần xóa mục đầu tiên. Làm thế nào tôi có thể làm điều đó một cách hiệu quả?



4
Không phải là một bản dupe. Câu hỏi trước là về việc loại bỏ các mục theo giá trị; đây là về việc loại bỏ một mục theo chỉ mục.
james.garriss

Câu trả lời:


154

Kích thước của mảng trong Java không thể thay đổi. Vì vậy, về mặt kỹ thuật, bạn không thể xóa bất kỳ phần tử nào khỏi mảng.

Một cách để mô phỏng việc xóa một phần tử khỏi mảng là tạo một mảng mới, nhỏ hơn, sau đó sao chép tất cả các phần tử từ mảng ban đầu vào mảng mới, nhỏ hơn.

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

Tuy nhiên , tôi sẽ không đề xuất phương pháp trên. Bạn thực sự nên sử dụng a List<String>. Danh sách cho phép bạn thêm và xóa các mục khỏi bất kỳ chỉ mục nào. Điều đó sẽ tương tự như sau:

List<String> list = new ArrayList<String>(); // or LinkedList<String>();
list.add("Stuff");
// add lots of stuff
list.remove(0); // removes the first item

32
Điều quan trọng cần lưu ý là loại bỏ phần tử đầu tiên của an ArrayListlà O (n).
Matthew Flaschen

1
@Matt, cho một mảng và danh sách. Tuy nhiên, mã dễ dàng hơn cho danh sách.
jjnguy

16
Đối với một mảng và một ArrayList, nhưng không phải đối với LinkedList.
Matthew Flaschen

4
Trên) ? tốt .. trong một mảng C? để loại bỏ phần tử nắm tay, bạn chỉ có thể tăng con trỏ O (1)
Hernán Eche

2
Đối với những người sử dụng Java dành cho Android như tôi, Arrays.copyOfRange()là cho API9 +
Sdghasemi

14

Cách đơn giản nhất có lẽ là như sau - về cơ bản bạn cần tạo một mảng mới nhỏ hơn một phần tử, sau đó sao chép các phần tử bạn muốn giữ lại vào đúng vị trí.

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

Lưu ý rằng nếu bạn thấy mình thực hiện loại thao tác này thường xuyên, đó có thể là dấu hiệu cho thấy bạn thực sự nên sử dụng một loại cấu trúc dữ liệu khác, ví dụ như danh sách được liên kết. Mỗi lần tạo một mảng mới là một phép toán O (n), có thể tốn kém nếu mảng của bạn lớn. Một danh sách liên kết sẽ cung cấp cho bạn O (1) loại bỏ phần tử đầu tiên.

Một ý tưởng thay thế là không xóa mục đầu tiên mà chỉ cần tăng một số nguyên trỏ đến chỉ mục đầu tiên đang được sử dụng. Người dùng của mảng sẽ cần phải tính đến phần bù này, nhưng đây có thể là một cách tiếp cận hiệu quả. Lớp Java String thực sự sử dụng phương thức này trong nội bộ khi tạo chuỗi con.


4
Đây không phải là cách dễ nhất về mặt kỹ thuật. Arrays.copyOfRange()Là.
jjnguy

4
Kể từ khi ông đang sử dụng Java6, ông có thể sử dụng Arrays.copyOfRange nhỏ gọn hơn
Thilo

1
@Justin - chắc chắn nhưng chỉ nếu bạn đang nhắm mục tiêu Java 1.6 hoặc cao hơn
mikera

1
thật. Nó không phải lúc nào cũng áp dụng được.
jjnguy

6
tiêu đề của câu hỏi làm cho nó rõ ràng rằng OP đang quan tâm đến câu trả lời cho Java 1.6 trở lên.
Stephen C

5

Bạn không thể làm điều đó một cách nhanh chóng. Mảng trong Java có kích thước cố định. Hai điều bạn có thể làm là:

  1. Chuyển mọi phần tử lên một, sau đó đặt phần tử cuối cùng thành null.
  2. Tạo một mảng mới, sau đó sao chép nó.

Bạn có thể sử dụng System.arraycopycho một trong hai. Cả hai đều là O (n), vì chúng sao chép tất cả trừ 1 phần tử.

Nếu bạn thường xuyên xóa phần tử đầu tiên, hãy cân nhắc sử dụng LinkedListthay thế. Bạn có thể sử dụng LinkedList.remove, đó là từ Queuegiao diện, để thuận tiện. Với LinkedList, loại bỏ phần tử đầu tiên là O (1). Trên thực tế, loại bỏ bất kỳ phần tử nào là O (1) khi bạn có một ListIteratorvị trí đó. Tuy nhiên, truy cập một phần tử tùy ý theo chỉ mục là O (n).


2

Giữ một chỉ mục của phần tử "sống" đầu tiên của mảng. Loại bỏ (giả vờ loại bỏ) phần tử đầu tiên sau đó trở thành một O(1)hoạt động phức tạp về thời gian.


0

Tóm lại, phương pháp danh sách liên kết nhanh:

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

-8

Một phương pháp xấu xí thay thế:

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

2
Làm ơn, một người có đủ uy tín phản đối câu trả lời này - nó chính xác như những gì nó nói - xấu xí! Không có ý định thô lỗ, nhưng vì lợi ích của sự dễ hiểu, xin vui lòng không đăng loại điều này!
Hack

nếu bạn đang sử dụng Mảng, nó sẽ là tốt hơn để sử dụng Arrays.copyOfRange
Bishal Gautam

Anh ấy yêu cầu cách tốt nhất .
Sapphire_Brick

xóa nó và xem bạn sẽ đạt được bao nhiêu danh tiếng.
Sapphire_Brick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.