ArrayList.clear () ve ArrayList.removeAll () arasındaki fark nedir?


283

O varsayarsak arraylistolarak tanımlanır ArrayList<String> arraylistolduğu arraylist.removeAll(arraylist)eşdeğer arraylist.clear()?

Öyleyse, clear()yöntemin dizi listesini boşaltmak için daha verimli olduğunu varsayabilir miyim ?

arraylist.removeAll(arraylist)Bunun yerine kullanımda uyarı var arraylist.clear()mı?


Bu sorunun olası bir sonucu: Biri diğeri yerine ne zaman kullanılabilir?
Corey Ogburn

3
@Corey: her biri ne zaman kullanmak isteyebilir arraylist.removeAll(arraylist)? Bunu yapmak için kesinlikle hiçbir neden göremiyorum.
Joachim Sauer

@Joachim Sauer Tam da bunu doğrulamak istedim. Teşekkürler +2. Peki elementData[i] = nullve arasındaki fark e.remove()önemli mi?
ateiob

arrList.removeAll(arrList)Bunun yerine akılcı bir neden yok arrList.clear(). arrList1.removeAll(arrList2)farklı bir konudur.
Vlad

3
Yalnızca removeAll () uygulaması bu satırla başlasaydı, tüm tartışma çok daha eğlenceli olabilirdi !!! if (c == this && !isEmpty()) { clear(); return true; }. Bunu bir yama olarak OpenJDK'ya göndermem gerekecek! ;-)
Julius Musseau

Yanıtlar:


396

İçin kaynak kodu clear():

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

(Kaynakta removeAll()tanımlandığı gibi AbstractCollection) için kaynak kodu :

public boolean removeAll(Collection<?> c) {
    boolean modified = false;
    Iterator<?> e = iterator();
    while (e.hasNext()) {
        if (c.contains(e.next())) {
            e.remove();
            modified = true;
        }
    }
    return modified;
}

clear() tüm bu ekstra yöntem çağrılarıyla uğraşmak zorunda olmadığından çok daha hızlıdır.

Ve Atrey'in işaret ettiği gibi, O (n ) yerine O (n 2 ) 'nin c.contains(..)zaman karmaşıklığını arttırır .removeAllclear


29
c.contains(...)Operasyonun zaman karmaşıklığını kareye alan bir not bu cevabı tamamlayacaktır.
Atreys

8
Bu konuda kaynak güçlü. (Diğer tüm cevaplara: Luke kaynağını kullanın.) Bir satır olarak ne kadar açık () uygulanabileceğine dikkat edin, size = 0; ancak çöp toplama, dizinin ulaşılamayan kısımlarındaki öğeleri toplamayı bilemez.
Julius Musseau

2
e.remove () çok daha karmaşık! e.remove () da, c.contains (...) gibi karmaşıklığı da kareler. Bir ArrayList'te e.remove (), dizinin geri kalanını birer birer kaydırması gereken ArrayList.remove (int dizini) öğesini çağırır.
Julius Musseau

1
@ateiob e.remove () iki ekstra yöntem çağrısı, bir aralık denetimi ve bir nesne dönüşü (dahili AbstractList.Itr.remove()ve için ArrayList.remove(int)) de
Atreys

2
@julius Bunu yaparsa: size = 0; elementData = new Object[10];geri kalan dizinin dış referansları olmadığından geri kalan her şey çöp toplanır.
corsiKa

51

Zaman karmaşıklığı ArrayList.clear()olduğunu O(n)ve removeAllDİR O(n^2).

Yani evet, ArrayList.clearçok daha hızlı.


15

clear()Yöntem, tek tüm unsurları ortadan kaldırır ArrayList. Dizi öğelerini ayarladığı için hızlı bir işlemdir null.

removeAll(Collection)Devralınan yöntem AbstractCollection, üzerinde yöntemini çağırın koleksiyonundan argüman koleksiyonunda bulunan tüm öğeleri kaldırır. İlgili koleksiyonlardan birini aramak zorunda olduğu için nispeten yavaş bir işlemdir.


Ben sadece herşeyi ayarladığını düşündüm. Durum böyle değilse, hangi öğelerin boş olarak ayarlanacağına nasıl karar verilir?
Farid

2
@Çok üzgünüm, İngilizcem burada çok resmi değil. Gerçekten de tüm unsurları boş olarak ayarladım. Ben tamir ederim!
Ernest Friedman-Hill

7

Çekler argümanı geçirilen eğer belirli bir optimizasyon olmadığı sürece removeAll()toplama kendisi (ve ben ise son derece şüphe böyle bir optimizasyon olduğunu) öyle olacak ölçüde bir basit daha yavaş .clear().

Bunun dışında (ve en azından eşit derecede önemli): arraylist.removeAll(arraylist)sadece geniş, kafa karıştırıcı bir kod. "Bu koleksiyonu temizle" demenin çok geri bir yoludur. Çok anlaşılır olana göre ne gibi bir avantajı olurdu arraylist.clear()?


7

Farklı amaçlara hizmet ederler. clear()sınıfın bir örneğini temizler removeAll(), verilen tüm nesneleri kaldırır ve işlemin durumunu döndürür.


daha fazla bilgi için yukarıdaki konuyu okumak için bir kaynak sağlayabilir misiniz
Kasun Siyambalapitiya

1
@KasunSiyambalapitiya İkisinin kaynak kodunu içeren kabul edilen cevaba ne dersiniz ?
Abdul

5

clear() temel Array'den geçecek ve her girişi null değerine ayarlayacak;

removeAll(collection)toplama için ArrayList kontrolünden geçecek ve remove(Object)eğer varsa.

Ben bunu clear()karşılaştırmak değil, çünkü removeAll sonra çok daha hızlı olduğunu hayal ediyorum .


2

Silinecek öğelerin üzerinden geçmediği için temizleme daha hızlıdır. Bu yöntem, TÜM öğelerin silinebileceğini varsayabilir.

Remove allmutlaka listedeki tüm öğeleri silmek anlamına gelmez, sadece parametre olarak sağlananlar silinmelidir. Bu nedenle, silinmemesi gerekenleri korumak için daha fazla çaba gerekmektedir.

AÇIKLAMA

'Döngü' ile, yani elemanın tutulup tutulmayacağını kontrol etmek zorunda değildir. nullSilinecek öğe listelerinde arama yapmadan başvuruyu ayarlayabilir .

ClearDaha hızlıdır deleteall.


1
Bunun ArrayList.clear()da ilmekli olduğundan eminim .
Joachim Sauer

@JVerstry clear () öğesinin ArrayList'ten kaldırdığı öğeleri silmediği anlamına mı geliyor ?
ateiob

1
Yanlış, temiz, iç dizi üzerinde döngü yapar ve çöp toplayıcının çalışmasını sağlamak için tüm başvuruları null değerine ayarlar.
devconsole

1
@Joachim, @devconsole: Bence parametre olarak verilen liste üzerinde döngü / yineleme yapmak zorunda kalmayacaktı. target.removeAll(param)yineleme olacak paramve daha sonra çağrı target.contains(...)üzerinde dolaşır ki target.
Vlad

2
-3 biraz serttir. JVerstry isterse, kendi Java uygulamasını sıfırdan sıfırdan yazabilirdi. clear () olabilir fizibil removeAll oysa () O (n) algoritması çeşit SAHİP OLMALIDIR bir döngü olmadan, O (1) uygulanacak, tüm unsurları inceleyerek olmadan removeAll () API sözleşme karşılamak için hiçbir yolu yoktur.
Julius Musseau

1

clear () çok daha verimli olacaktır. Sadece her bir öğeyi kaldıracaktır. RemoveAll (arraylist) kullanmak çok daha fazla iş gerektirecektir, çünkü arraylist içindeki her öğeyi kaldırmadan önce arraylist'te olup olmadığını kontrol edecektir.


-8

Array => çalışma zamanında bir Array değişkeni için boşluk ayrıldıktan sonra, ayrılan alan genişletilemez veya kaldırılamaz.

ArrayList => Arraylist için durum böyle değil. ArrayList çalışma zamanında büyüyebilir ve küçülebilir. Tahsis edilen alan çalışma zamanında küçültülebilir veya büyütülebilir.


Bu, ArrayList.clear () ve ArrayList.removeAll () arasındaki fark olan soruya cevap vermez, Array ve ArrayList arasındaki fark değil.
Pierre

Bu cevap gereksiz. Sorunun konusu bu değil.
Serafim Costa
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.