JavaDocs ve Stuart Marks'ın (veya önceki sürümlerinin) bu konuşmasına bakın .
Kod örnekleri için aşağıdakileri kullanacağım:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Yapısal değişmezlik (Veya: değiştirilemezlik)
Yapısal olarak değiştirmeye yönelik herhangi bir girişim List.of
, bir UnsupportedOperationException
. Bu, ekleme , ayarlama ve kaldırma gibi işlemleri içerir . Bununla birlikte, listedeki nesnelerin içeriğini değiştirebilirsiniz (nesneler değişmez değilse), böylece liste "tamamen değişmez" olmaz.
Bu, ile oluşturulan değiştirilemez listeler için aynı kaderdir Collections.unmodifiableList
. Yalnızca bu liste orijinal listenin bir görünümüdür , dolayısıyla orijinal listeyi değiştirirseniz değişebilir.
Arrays.asList
tamamen değişmez değildir, üzerinde bir kısıtlama yoktur set
.
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
Benzer şekilde, destek dizisini değiştirmek (tutarsanız) listeyi değiştirir.
Yapısal değişmezlik, savunma kodlaması, eşzamanlılık ve güvenlikle ilgili olarak bu cevabın kapsamı dışında kalan birçok yan etkiyle birlikte gelir.
Boş düşmanlık
List.of
ve Java 1.5'ten beri herhangi bir koleksiyon null
bir öğe olarak izin vermez . null
Bir öğe olarak geçmeye çalışmak veya hatta bir arama, bir NullPointerException
.
Yana Arrays.asList
1.2 dan bir koleksiyon (Koleksiyonları Framework), o verir null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Serileştirilmiş form
Yana List.of
Java 9 tanıtılan ve bu yöntemle oluşturulan listeler kendi (ikili) tefrika formu var olmuştur, daha önce JDK sürümleri (hayır üzerine serisi kaldırılan olamaz ikili uyumluluk ). Ancak, örneğin JSON ile de / serileştirebilirsiniz.
Kimlik
Arrays.asList
new ArrayList
referans eşitsizliğini garanti eden dahili çağrılar .
List.of
dahili uygulamaya bağlıdır. Döndürülen örnekler referans eşitliğine sahip olabilir, ancak bu garanti edilmediğinden buna güvenemezsiniz.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
List.equals
Nasıl oluşturulduklarına veya hangi işlemleri desteklediklerine bakılmaksızın, aynı öğeleri aynı sırayla içeriyorlarsa listelerin eşit (aracılığıyla ) olduğunu belirtmek gerekir .
asList.equals(listOf); // true i.f.f. same elements in same order
Uygulama (uyarı: ayrıntılar sürümlere göre değişebilir)
Listesindeki öğe sayısı List.of
2 veya daha azsa, öğeler özel (dahili) bir sınıfın alanlarında saklanır. Bir örnek, 2 öğeyi (kısmi kaynak) depolayan listedir:
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
Aksi takdirde, ile benzer şekilde bir dizide saklanırlar Arrays.asList
.
Zaman ve Mekan verimliliği
List.of
Alan bazlı (boyut <2) olan uygulamalar bazı işlemler ile biraz daha hızlı yapar. Örnek olarak, size()
dizi uzunluğunu getirmeden bir sabit döndürebilir ve contains(E e)
yineleme ek yükü gerektirmez.
Değiştirilemez bir liste oluşturmak List.of
da daha hızlıdır. Yukarıdaki yapıcıyı 2 referans atamasıyla (ve hatta keyfi sayıda öğe için olanı) karşılaştırın:
Collections.unmodifiableList(Arrays.asList(...));
bu 2 liste artı diğer ek yükler oluşturur. Alan açısından, UnmodifiableList
ambalajı ve birkaç kuruş tasarruf edersiniz . Sonuçta, HashSet
eşdeğerdeki tasarruf daha ikna edicidir.
Sonuç zamanı: List.of
değişmeyen Arrays.asList
bir liste istediğinizde ve değişebilen bir liste istediğinizde kullanın (yukarıda gösterildiği gibi).