Arrays.asList () so với Collections.singletonList ()


136

Có một lợi thế (hoặc nhiều sự khác biệt) khi sử dụng Arrays.asList (một cái gì đó) so với Collections.singletonList (một cái gì đó) để tạo một danh sách chứa một mục không? Cái sau làm cho danh sách trả về là bất biến.


8
Bạn có thể ném Guava ImmutableList.of()Lists.newArrayList()hỗn hợp là tốt.
biziclop

Ngoài ra, tôi đã gặp phải Collections.singletonList () khi một phương thức trả về một Danh sách mà sau đó được sửa đổi.
Howard Grimberg

1
Java 10 có danh sách bất biến thực sự: stackoverflow.com/a/52536126/1216775
akhil_mittal

Câu trả lời:


204

Collections.singletonList(something)bất biến trong khi đó Arrays.asList(something)Listbiểu diễn kích thước cố định của một mảng trong đó Danh sách và mảng được nối trong heap.

Arrays.asList(something)cho phép các thay đổi phi cấu trúc được thực hiện với nó, được phản ánh cho cả Danh sách và mảng liên kết. Nó ném UnsupportedOperationExceptionđể thêm, xóa các phần tử mặc dù bạn có thể đặt một phần tử cho một chỉ mục cụ thể.

Mọi thay đổi được thực hiện cho Danh sách được trả về Collections.singletonList(something)sẽ dẫn đến UnsupportedOperationException.

Ngoài ra, dung lượng của Danh sách được trả về Collections.singletonList(something)sẽ luôn là 1 không giống như Arrays.asList(something)dung lượng của nó sẽ là kích thước của mảng được hỗ trợ.


63

Tôi chỉ muốn nói thêm rằng danh sách đơn không được hỗ trợ bởi một mảng và chỉ có một tham chiếu đến một mục đó. Có lẽ, nó sẽ chiếm ít bộ nhớ hơn và có thể là đáng kể tùy thuộc vào số lượng danh sách bạn muốn tạo.


Bất kỳ liên kết hoặc mã để sao lưu điểm hiệu quả bộ nhớ này? Tôi có Arrays.asList (ONLY_ONE_OB DỰ ÁN) này được viết rất nhiều trên một cơ sở mã và muốn tìm hiểu xem việc thay thế bằng Collections.singletonList () có dẫn đến hiệu quả bộ nhớ không?
Rahul Saini


12

Phương thức Arrays.asListtrả về một danh sách kích thước cố định được hỗ trợ bởi mảng đã chỉ định. Phương thức trả về một thể hiện của ArrayListnó là một lớp tĩnh riêng được mở rộng AbstractListvà không java.util.ArrayList. Lớp tĩnh này cung cấp thực hiện vài phương pháp ví dụ set, indexOf, forEach, replaceAllvv nhưng khi chúng ta invoke addnó không có thực hiện riêng, thay vì phương pháp của nó từ AbstractListđược gọi mà ném java.lang.UnsupportedOperationException.

Trả Collections.singletonListvề một danh sách bất biến chỉ chứa đối tượng được chỉ định và nó cũng được tuần tự hóa.

Mặt khác, đối với các danh sách không thay đổi, chúng tôi thường sử dụng Collections.unmodifiableListđể trả về một chế độ xem không thể thay đổi của danh sách đã chỉ định.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

Bộ sưu tập chế độ xem không thể thay đổi là một bộ sưu tập không thể thay đổi và cũng là chế độ xem trên bộ sưu tập sao lưu. Lưu ý rằng những thay đổi đối với bộ sưu tập sao lưu vẫn có thể xảy ra và nếu chúng xảy ra, chúng có thể được nhìn thấy qua chế độ xem không thể thay đổi.

Chúng ta có thể có một danh sách bất biến thực sự trong Java 10 trở lên. Có hai cách để có được danh sách thực sự không thể thay đổi :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Nếu bất kỳ một trong hai biến này được sử dụng, giá trị vẫn sẽ là "Apple" chứ không phải "Apricot".

Theo tài liệu của Java 10 :

Các phương thức List.ofList.copyOfnhà máy tĩnh cung cấp một cách thuận tiện để tạo các danh sách không thể thay đổi. Các thể hiện Danh sách được tạo bởi các phương thức này có các đặc điểm sau:

  1. Họ là không thể thay đổi . Các yếu tố không thể được thêm, loại bỏ hoặc thay thế. Gọi bất kỳ phương thức trình biến đổi nào trong Danh sách sẽ luôn UnsupportedOperationExceptionbị ném. Tuy nhiên, nếu các thành phần được chứa là chính chúng có thể thay đổi, điều này có thể khiến nội dung của Danh sách dường như thay đổi.
  2. Họ không cho phép các phần tử null. Nỗ lực tạo ra chúng với các yếu tố null dẫn đến NullPointerException.
  3. Chúng được tuần tự hóa nếu tất cả các yếu tố là tuần tự hóa.
  4. Thứ tự của các phần tử trong danh sách giống như thứ tự của các đối số được cung cấp hoặc của các phần tử trong mảng được cung cấp.
  5. Họ là value-based. Người gọi không nên đưa ra giả định về danh tính của các trường hợp được trả lại. Các nhà máy được tự do tạo ra các trường hợp mới hoặc tái sử dụng các trường hợp hiện có. Do đó, các hoạt động nhạy cảm với danh tính trong các trường hợp này (đẳng thức tham chiếu (==), mã băm nhận dạng và đồng bộ hóa) là không đáng tin cậy và nên tránh.
  6. Chúng được tuần tự hóa như được chỉ định trên trang Biểu mẫu nối tiếp .
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.