JavaRush /Blog Java /Random-VI /Khởi tạo cú đúp
Joysi
Mức độ

Khởi tạo cú đúp

Xuất bản trong nhóm

1. Khởi tạo cú đúp

Khởi tạo bằng dấu ngoặc kép ( sau đây gọi là Khởi tạo dấu ngoặc kép ) là một công cụ Java để tạo các bộ sưu tập như danh sách, tập hợp và ánh xạ đồng thời với khai báo của chúng.
Khởi tạo cú đúp - 1
Khi bạn cần danh sách có các phần tử cố định, chẳng hạn như danh sách các sản phẩm được hỗ trợ hoặc đơn vị tiền tệ, việc khai báo danh sách cùng lúc với việc khởi tạo sẽ cải thiện khả năng đọc mã. Đây là lý do tại sao việc khởi tạo cú đúp đang trở nên phổ biến, vì không có phương pháp tiêu chuẩn nào khác để tạo các bộ sưu tập có khởi tạo đồng thời trong mã. Thật không may, không giống như các ngôn ngữ lập trình khác, Java không hỗ trợ các bộ sưu tập chữ. Do hạn chế này, việc tạo một Danh sách không thể sửa đổi với một số lượng nhỏ phần tử buộc chúng ta phải viết nhiều dòng mã dưới dạng các lệnh gọi lặp lại add()để thêm các phần tử mong muốn với gói cuối cùng:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Đây là một mô tả dư thừa không cần thiết có thể được đơn giản hóa. Hãy điền vào danh sách tĩnh theo cách thuận tiện cho chúng ta, cụ thể là trực tiếp trong các khối tĩnh trong quá trình khởi tạo, đây là điều mà Double braceviệc khởi tạo sẽ giúp chúng ta, cho phép chúng ta viết mọi thứ trong một dòng:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
Tương tự Double braceviệc khởi tạo sẽ giúp chúng ta điền các giá trị và HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
Tất cả đều trông rất thanh lịch, nhưng nó có nhược điểm, khiến cho việc khởi tạo cú đúp đôi trở thành phản mẫu. Chúng ta sẽ xem xét chúng sâu hơn trong chương tiếp theo.

Ưu và nhược điểm của việc khởi tạo cú đúp.

DoubleKhởi tạo cú đúp sử dụng việc tạo một lớp bên trong ẩn danh . Tuy nhiên, những gì ban đầu bị ẩn trên bề mặt, Double braceviệc khởi tạo sẽ tạo ra một lớp với sự khởi tạo thêm thể hiện của nó mỗi khi bạn sử dụng nó. Ngoài ra, một tham chiếu ẩn đến lớp riêng tư này được sử dụng, điều này có thể khiến chúng ta bị rò rỉ bộ nhớ. Bạn cũng không thể sử dụng toán tử ghost cho generic (toán tử kim cương < >), vì chúng ta không thể truy cập vào bên trong một lớp ẩn danh.
(Từ người dịch: Một lần nữa chi tiết hơn:
sau lớp đầu tiên {, một lớp ẩn danh nội bộ được tạo, sau lớp thứ hai, {quá trình khởi tạo xảy ra khi tạo một phiên bản của lớp, trong đó chúng ta có quyền truy cập vào các trường và phương thức của lớp bên ngoài ( liên quan đến lớp ẩn danh).)
Ưu điểm:
  1. Giảm dòng trong mã
  2. Tạo và khởi tạo trong một biểu thức.
Nhược điểm:
  1. Tạo một lớp ẩn danh ẩn khỏi bạn.
  2. Điều này khiến chúng tôi phải trả thêm chi phí cho phiên bản của nó mỗi khi chúng tôi sử dụng nó.
  3. Mỗi lần một tham chiếu ẩn được tạo ra, điều này có thể dẫn đến rò rỉ bộ nhớ.
Nhận định: Do những nhược điểm trên và sự tồn tại của các lựa chọn thay thế cho cú đúp, việc khởi tạo được coi là một phản mẫu trong thế giới Java. Cứu mèo con

Các lựa chọn thay thế cho việc khởi tạo cú đúp trong Java

Tin vui là có nhiều cách khác để đạt được mục tiêu tương tự trong Java. Chúng ta có thể triển khai trong một dòng mã việc tạo và khởi tạo một ArrayList bằng cách sử dụng hàm tạo Copy từ lớp Collection như dưới đây:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()sẽ trả về cho chúng tôi danh sách độ dài cố định được truyền cho ArrayListhàm tạo bản sao. Hãy ghi nhớ sự khác biệt giữa các danh sách có độ dài cố định được trả về từ Arrays.asList()Collections.unmodifiableList(): bạn không thể thêm hoặc xóa các phần tử ArrayListcủa - , nhưng bạn có thể thay đổi một phần tử theo chỉ mục bằng cách sử dụng set(), điều mà bạn không thể thực hiện với danh sách được trả về bởi Collections.unmodifiableList(). Nếu bạn muốn lấy một danh sách nhỏ thì đây là cách tốt nhất, mặc dù nó sẽ kém minh bạch hơn đối với Setcác bộ sưu tập khác, vì vậy bạn sẽ phải tạo nó Listtrước khi tạo Set-a. Nhưng điều này vẫn tốt hơn so với khởi tạo cú đúp, vì trong trường hợp này, một lớp ẩn danh nội bộ bổ sung không được tạo mỗi khi nó được sử dụng. Nếu bạn đang chạy Java 8, bạn có một phương pháp thay thế khác. API luồng JDK 8 sẽ giúp bạn tạo các bộ sưu tập nhỏ bằng cách kết hợp Stream Factorycác phương thức đầu ra thành một bộ sưu tập List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
Setbạn có thể sử dụng Collectors.toSet()phương pháp thay thế Collectors.toList()như dưới đây:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
Nhân tiện, Stream collectcác phương thức không đảm bảo rằng các bộ sưu tập mà chúng tạo ra được bảo vệ khỏi những thay đổi. Trong Java 8, các bộ sưu tập mà chúng trả về (chẳng hạn như - ArrayList, HashSetHashMap) khá phổ biến (chúng ta có thể thay đổi chúng), nhưng thực tế này có thể được sửa trong các bản phát hành JDK trong tương lai. Bây giờ đó là tất cả về Double braceviệc khởi tạo trong Java. Mẫu này có thể chấp nhận được để thử nghiệm và demo nhưng không đủ tốt để sử dụng trong sản xuất. Do những nhược điểm cố hữu của nó, việc khởi tạo cú đúp ngày nay đã trở thành một mô hình phản đối, đặc biệt là khi có các lựa chọn thay thế có sẵn. Bản thân tôi vẫn sử dụng cấu trúc này để khởi tạo bản đồ tĩnh và thế là xong. Vì Listtôi thích tạo Collectionsbằng cách kết hợp với việc tạo Array.asListtrong hàm tạo của nó. Và nếu tôi sử dụng Java 8 - một thiết kế sử dụng API Stream và collect(). Các bài viết liên quan: Nếu bạn thích hướng dẫn này và muốn tìm hiểu thêm về các mẫu, nguyên tắc và cách thực hành tốt nhất trong lập trình Java, bạn cũng có thể muốn xem các bài viết khác trên trang web của chúng tôi . Đề xuất đọc: Nếu bạn muốn tìm hiểu thêm về các mô hình và phương pháp hay nhất, bạn nên đọc Lập trình hiệu quả của Joshua Bloch , không cuốn sách nào có thể thay thế được. Và nếu bạn đã thành thạo Java và đang tìm một cuốn sách về các mẫu thiết kế, có phong cách trình bày hài hước thú vị và dễ đọc, hãy chú ý đến “Head First. Mẫu thiết kế" .
Từ người dịch: Tôi đã cố tình cung cấp một liên kết đến cuốn sách gốc của Bloch, vì bản dịch sang tiếng Nga của nó không thành công (ví dụ: Builder = constructor).
Bản dịch bài viết Khởi tạo cú đúp trong Java là gì? Ví dụ về Anti Pattern (xuất bản tháng 10 năm 2015).
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION