2012-11-18 21 views
5

Java'nın Liste arabiriminin nesnelerini, mutasyonun artık gerekli olmadığı zamanda değiştirilemez bir eşdeğere dönüştürmek güzel olurdu. Yani, istemci List'i değişmez yapan freeze yöntemini arayabilir. Bana hemen faydası, derin kopyalama masrafı olmadan iş parçacığı güvenliği. (Edit: Tüm iş parçacıklarının kullanması için ekstra bir değişmez kopyanın uygun maliyetli olduğunu varsayarsak, kullanıcılar doğru olur.)Bir Java Listesindeki mutabiliteyi devre dışı bırakma

Böyle bir özellik sağlayan üçüncü taraf bir arabirim veya sınıf var mı?

+1

Bunlardan birini mi kastediyorsunuz? http://download.oracle.com/javase/6/docs/api/java/util/Collections.html?is-external=true#unmodifiableList(java.util.List). Kendi listenizi (strateji olarak) oluşturabilir ve dondurma yöntemi çağrıldığında, değişmez bir liste için dahili listeyi değiştirirsiniz. – Augusto

cevap

1

CopyOnWriteArrayList'u kullanmayı deneyin. listesi yerine altta yatan bir dizi modifiye, yeni bir dizi oluşturulur ve eski dizi atılır, değiştirilmiş olduğunda

CopyOnWriteArrayList .O dışında çok ArrayList sınıf gibi davranır. Bu olduğu anlamına gelir dahili değişmez ve bu nedenle ilgili senkronizasyon ya gerektirmeden geçişi için kullanılabilir yatan CopyOnWriteArrayList .O nesnenin tadını bir referans tutan bir arayan bir yineleyici alır (yani copyOnWriteArrayListRef.iterator()), copyOnWriteArrayListRef listesinden veya klonuna() kopyalamadan önce copyOnWriteArrayListRef listesi (eşzamanlı modifikasyon riski yoktur) ve da daha iyi performans sunar.

3

Guava kütüphanelerinin bir parçası olarak bir ImmutableList sınıfı vardır. Mevcut bir Iterable'dan ImmutableList oluşturmak için copyOf yöntemini kullanabilirsiniz. İstemci hala orijinal değişken listesine bir başvuru varsa Collections.unmodifiableList kullanarak Doğrudan

List<String> immutableList = ImmutableList.copyOf(list);

1

yeterli değildir.

Ben tüm yöntemin kendisine çağırır orijinal değişken listesi (temsilci) için dahili bir referans var ve ileri verecek bir delegating liste uygulaması yaratacak. Bu kodu elle yazmak bir PITA'dır, ancak Eclipse örneğin sizin için otomatik olarak üretebilir.

Sonra freeze yöntemini çağırarak üzerine, ben FreezingList sadece unmodifable görünüm sayesinde orijinal temsilci gitmek için gelecekteki yöntemin tüm çağrıları olmasını sağlar Collections.unmodifiableList ile orijinal listeyi kaydırmak istiyorum.

İşleri daha güvenli, ancak daha az esnek hale getirmek için, aşağıdaki kurucuyu değiştirebilir ve orijinal listeyi kendisine aktarmaya (yerine orijinal değiştirilebilen listeyi istemciye bırakabilir) yerine listeyi dahili olarak başlatabilirsiniz (örneğin ArrayList olarak).

public class FreezingList<E> implements List<E> { 

    // the original list you delegate to (the delegate) 
    private List<E> list; 

    private boolean frozen = false; 

    public FreezingList(List<E> list) { 
     this.list = list; 
    } 

    public void freeze() { 
     if (!frozen) { 
      list = Collections.unmodifiableList(list); 
      frozen = true; 
     } 
    } 

    // all the delegating methods follow: 
    public int size() { 
     return list.size(); 
    } 

    public E get(int index) { 
     return list.get(index); 
    } 
    // etc. etc. 
} 
İlgili konular