Khởi tạo danh sách Java trong một dòng

1. Giới thiệu

Trong hướng dẫn nhanh này, chúng tôi sẽ tìm hiểu cách chúng tôi có thể khởi tạo Danh sách bằng cách sử dụng một lớp lót.

2. Tạo từ một mảng

Chúng ta có thể tạo một Danh sách từ một mảng và nhờ các ký tự mảng mà chúng ta có thể khởi tạo chúng trong một dòng:

List list = Arrays.asList(new String[]{"foo", "bar"});

Chúng ta có thể tin tưởng cơ chế varargs để xử lý việc tạo mảng. Bằng cách đó, chúng ta có thể viết mã ngắn gọn và dễ đọc hơn:

@Test public void givenArraysAsList_thenInitialiseList() { List list = Arrays.asList("foo", "bar"); assertTrue(list.contains("foo")); }

Ví dụ kết quả của mã này thực hiện giao diện Danh sách nhưng nó không phải là java.util.ArrayList cũng không phải là LinkedList . Thay vào đó, nó là một Danh sách được hỗ trợ bởi mảng ban đầu có hai hàm ý.

Mặc dù, tên của lớp là ArrayList nhưng nằm trong gói java.util.Arrays .

2.1. Kích thước cố định

Phiên bản kết quả từ Arrays.asList sẽ có kích thước cố định:

@Test(expected = UnsupportedOperationException.class) public void givenArraysAsList_whenAdd_thenUnsupportedException() { List list = Arrays.asList("foo", "bar"); list.add("baz"); }

2.2. Tham chiếu được Chia sẻ

Mảng ban đầu và danh sách chia sẻ cùng một tham chiếu đến các đối tượng:

@Test public void givenArraysAsList_whenCreated_thenShareReference(){ String[] array = {"foo", "bar"}; List list = Arrays.asList(array); array[0] = "baz"; assertEquals("baz", list.get(0)); }

3. Tạo từ một luồng (Java 8)

Chúng tôi có thể dễ dàng chuyển đổi Luồng thành bất kỳ loại Bộ sưu tập nào.

Do đó, với các phương thức gốc cho Luồng , chúng ta có thể tạo và khởi tạo danh sách trong một dòng:

@Test public void givenStream_thenInitializeList(){ List list = Stream.of("foo", "bar") .collect(Collectors.toList()); assertTrue(list.contains("foo")); }

Ở đây chúng ta nên đánh dấu rằng Collectors.toList () không đảm bảo việc triển khai chính xác Danh sách trả về .

Không có hợp đồng chung nào về khả năng thay đổi, khả năng tuần tự hóa hoặc an toàn luồng của phiên bản trả về. Do đó, mã của chúng tôi không nên dựa vào bất kỳ thuộc tính nào trong số này.

Một số nguồn nhấn mạnh rằng Stream.of (…) .collect (…) có thể có bộ nhớ và hiệu suất lớn hơn Arrays.asList () nhưng trong hầu hết các trường hợp, đó là một tối ưu hóa vi mô nên có rất ít sự khác biệt.

4. Phương thức Nhà máy (Java 9)

Trong JDK 9, một số phương pháp nhà máy thuận tiện đã được giới thiệu cho các bộ sưu tập:

List list = List.of("foo", "bar", "baz"); Set set = Set.of("foo", "bar", "baz");

Một chi tiết quan trọng là các phiên bản trả về là không thay đổi . Ngoài ra, các phương pháp nhà máy có một số lợi thế về hiệu quả không gian và an toàn sợi.

Chủ đề này được khám phá nhiều hơn trong bài viết này.

5. Khởi tạo Double-Brace

Ở một số nơi, chúng ta có thể tìm thấy một phương thức được gọi là 'khởi tạo dấu ngoặc kép' trông giống như sau:

@Test public void givenAnonymousInnerClass_thenInitialiseList() { List cities = new ArrayList() {{ add("New York"); add("Rio"); add("Tokyo"); }}; assertTrue(cities.contains("New York")); }

Tên 'khởi tạo dấu ngoặc kép' khá dễ gây hiểu lầm. Cú pháp có thể trông nhỏ gọn và thanh lịch nhưng nó ẩn một cách nguy hiểm những gì đang diễn ra dưới mui xe.

Thực ra không có phần tử cú pháp 'dấu ngoặc kép' trong Java, đó là hai khối được định dạng có chủ đích theo cách này.

Với dấu ngoặc nhọn bên ngoài, chúng tôi khai báo một lớp bên trong ẩn danh sẽ là một lớp con của ArrayList . Bên trong các dấu ngoặc nhọn này, chúng ta có thể khai báo các chi tiết của lớp con của chúng ta.

Như thường lệ, chúng ta có thể sử dụng các khối khởi tạo cá thể và đó là nơi bắt nguồn của cặp dấu ngoặc nhọn bên trong.

Sự ngắn gọn của cú pháp này rất hấp dẫn tuy nhiên nó được coi là một phản mẫu.

Để đọc thêm về khởi tạo dấu ngoặc kép, hãy xem bài viết của chúng tôi tại đây.

6. Kết luận

Java hiện đại cung cấp một số tùy chọn để tạo Bộ sưu tập trong một dòng. Phương pháp chúng tôi chọn gần như hoàn toàn phụ thuộc vào sở thích cá nhân, thay vì lý luận kỹ thuật.

Một điều quan trọng cần rút ra là, mặc dù trông có vẻ duyên dáng, nhưng kiểu khởi tạo lớp bên trong ẩn danh (hay còn gọi là 'dấu ngoặc kép') có nhiều tác dụng phụ tiêu cực .

Như mọi khi, mã có sẵn trên GitHub.