วิธีที่ดีที่สุดในการลบองค์ประกอบแรกออกจากอาร์เรย์คืออะไร?


87

ฉันมีสตริงอาร์เรย์ ( String[]) และฉันต้องการลบรายการแรก ฉันจะทำอย่างมีประสิทธิภาพได้อย่างไร?



4
ไม่ใช่คนหลอกลวง คำถามก่อนหน้านี้เกี่ยวกับการลบรายการตามมูลค่า นี่คือการลบรายการตามดัชนี
james.garriss

คำตอบ:


158

ไม่สามารถเปลี่ยนขนาดของอาร์เรย์ใน 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

34
สิ่งสำคัญคือต้องสังเกตว่าการลบองค์ประกอบแรกของ an ArrayListis O (n)
Matthew Flaschen

1
@Matt สำหรับอาร์เรย์และรายการ แต่รหัสเป็นวิธีที่ง่ายกว่าสำหรับรายการ
jjnguy

16
สำหรับอาร์เรย์และArrayListแต่ไม่ใช่สำหรับLinkedList.
Matthew Flaschen

4
บน) ? ดี .. ในอาร์เรย์ C? หากต้องการลบองค์ประกอบกำปั้นคุณสามารถเพิ่มตัวชี้ O (1)
Hernán Eche

3
สำหรับผู้ที่ใช้ Java สำหรับ Android เช่นฉันใช้Arrays.copyOfRange()สำหรับ API9 +
Sdghasemi

15

วิธีที่ง่ายที่สุดอาจเป็นดังนี้ - โดยพื้นฐานแล้วคุณต้องสร้างอาร์เรย์ใหม่ที่มีขนาดเล็กกว่าหนึ่งองค์ประกอบจากนั้นคัดลอกองค์ประกอบที่คุณต้องการเก็บไว้ในตำแหน่งที่ถูกต้อง

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 ที่กะทัดรัดกว่า
Thilo

1
@Justin - แน่นอน แต่ถ้าคุณกำหนดเป้าหมายเป็น Java 1.6 ขึ้นไปเท่านั้น
mikera

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)


3

เก็บดัชนีขององค์ประกอบ "สด" แรกของอาร์เรย์ การลบ (แกล้งทำเป็นลบ) องค์ประกอบแรกจะกลายเป็นการO(1)ดำเนินการที่มีความซับซ้อนของเวลา


0

สรุปวิธีการเชื่อมโยงอย่างรวดเร็ว:

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

-10

วิธีอื่นที่น่าเกลียด:

   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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.