Bir diziden ilk öğeyi kaldırmanın en iyi yolu nedir?


Yanıtlar:


158

Java'daki dizilerin boyutu değiştirilemez. Bu nedenle, teknik olarak diziden herhangi bir öğe kaldıramazsınız.

Diziden bir öğeyi kaldırmanın bir yolu, yeni, daha küçük bir dizi oluşturmak ve ardından tüm öğeleri orijinal diziden yeni, daha küçük diziye kopyalamaktır.

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

Ancak yukarıdaki yöntemi önermem. Gerçekten bir List<String>. Listeler, herhangi bir dizinden öğe eklemenizi ve kaldırmanızı sağlar. Bu, aşağıdakine benzer görünür:

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'ın ilk elemanının kaldırılmasının ArrayListO (n) olduğuna dikkat etmek önemlidir .
Matthew Flaschen

1
@Matt, bir dizi ve liste için. Ancak kod, liste için çok daha kolay.
jjnguy

16
Bir dizi ve bir için ArrayList, ama için değil LinkedList.
Matthew Flaschen

4
O (n)? iyi .. bir C dizisinde? yumruk elemanını kaldırmak için sadece işaretçiyi artırabilirsiniz O (1)
Hernán Eche

3
Benim gibi Android için Java kullananlar için, Arrays.copyOfRange()API9 + içindir
Sdghasemi

15

En basit yol muhtemelen aşağıdaki gibidir - temelde bir eleman daha küçük olan yeni bir dizi oluşturmanız ve ardından tutmak istediğiniz öğeleri doğru konumlara kopyalamanız gerekir.

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

Kendinizi bu tür bir işlemi sık sık yaparken bulursanız, bunun aslında farklı türde bir veri yapısı, örneğin bağlantılı bir liste kullanmanız gerektiğinin bir işareti olabileceğini unutmayın. Her seferinde yeni bir dizi oluşturmak bir O (n) işlemidir ve diziniz büyükse pahalıya mal olabilir. Bağlantılı bir liste size ilk elemanın O (1) kaldırılmasını sağlayacaktır.

Alternatif bir fikir, ilk öğeyi hiç kaldırmak değil, sadece kullanımda olan ilk dizini işaret eden bir tamsayıyı artırmaktır. Dizinin kullanıcılarının bu farkı hesaba katması gerekecektir, ancak bu verimli bir yaklaşım olabilir. Java String sınıfı, alt dizeler oluştururken aslında bu yöntemi dahili olarak kullanır.


4
Bu teknik olarak en kolay yol değil. Arrays.copyOfRange()dır-dir.
jjnguy

4
Java6 kullandığı için, daha kompakt Arrays.copyOfRange
Thilo

1
@Justin - elbette, ancak yalnızca Java 1.6 veya üstünü hedefliyorsanız
mikera

1
doğru. Her zaman uygulanabilir değildir.
jjnguy

6
Söz ait başlıklar, OP olduğunu temizlemek yapar edilir Java 1.6 ve üstü cevapları ilgilenen.
Stephen C

5

Hızlıca bırakın, hiç yapamazsınız. Java'daki diziler sabit boyuttadır. Yapabileceğiniz iki şey:

  1. Her öğeyi bir yukarı kaydırın, ardından son öğeyi boş olarak ayarlayın.
  2. Yeni bir dizi oluşturun ve kopyalayın.

System.arraycopyBunlardan herhangi biri için kullanabilirsiniz . Bunların ikisi de O (n) 'dir, çünkü 1 eleman hariç hepsini kopyaladılar.

İlk öğeyi sık sık kaldıracaksanız, LinkedListbunun yerine kullanmayı düşünün . Kolaylık sağlamak LinkedList.removeiçin Queuearayüzden olanı kullanabilirsiniz . İleLinkedList , ilk elemanın kaldırılması O (1) 'dir. Aslında, ListIteratoro konuma bir kez ulaştığınızda herhangi bir öğeyi kaldırmak O (1) 'dir . Bununla birlikte, indeksle rastgele bir elemana erişim O (n) 'dur.


3

Dizinin ilk "canlı" öğesinin bir dizinini tutun. İlk öğeyi kaldırmak (kaldırıyormuş gibi yapmak) daha sonra bir O(1)zaman karmaşıklığı işlemi haline gelir .


0

Özetlemek gerekirse, hızlı bağlantılı liste yöntemi:

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

-10

Alternatif bir çirkin yöntem:

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

2
Lütfen, yeterli itibara sahip biri bu yanıta olumsuz oy veriyor - tam da söylediği gibi - çirkin! Kaba olma niyeti yok, ancak kodlanabilirlik adına lütfen bu tür şeyler yayınlamayın!
Hack5

Zaten Arrays kullanıyorsanız, Arrays.copyOfRange
Gautam

En iyi yolu istedi .
Sapphire_Brick

onu silin ve ne kadar itibar kazanacağınızı görün.
Sapphire_Brick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.