JavaRush /Blog Java /Random-VI /new ArrayList(????) khởi tạo như thế nào và ở đâu tốt hơn...
Vovan
Mức độ

new ArrayList(????) khởi tạo như thế nào và ở đâu tốt hơn

Xuất bản trong nhóm
Viết mã mà không sử dụng khung bộ sưu tập sẽ là một điều điên rồ. Đây là một phần tuyệt vời của Java với nhiều giải pháp hữu ích. Quan trọng hơn, không giống như mảng, bạn không phải lo lắng về kích thước. ArrayList sẽ phát triển cho đến khi hết bộ nhớ. Nhà phát triển không phải lo lắng về kích thước ban đầu và lỗi ArrayIndexOutOfBoundsException . Nhưng nếu có điều kiện theo dõi dung lượng bộ nhớ thì sao? Chúng ta có thể sử dụng bộ nhớ một cách hiệu quả khi làm việc với các bộ sưu tập không?
Một câu hỏi tiêu chuẩn được đặt ra: làm thế nào để khởi tạo một danh sách? Mã bên dưới sẽ không hoạt động: Nó sẽ dẫn đến lỗi biên dịch: Tên biến cục bộ có thể chưa được khởi tạo . Đặc tả Java yêu cầu tất cả các biến cục bộ (những biến tồn tại trên ngăn xếp) phải được khởi tạo với các giá trị thích hợp. Đây là cách bạn có thể thực hiện: Không còn nghi ngờ gì nữa, danh sách phải được khởi tạo. Bạn có thể tạo danh sách trên dòng đầu tiên hoặc bạn có thể làm điều gì đó thông minh hơn và sử dụng khởi tạo lười biếng như chúng tôi đã làm trong phương thức getAllNames() . Trong trường hợp này, danh sách sẽ chỉ được tạo khi cần thiết - nếu các điều kiện ban đầu không được đáp ứng, danh sách sẽ không bao giờ xuất hiện trên vùng nhớ heap. Ở đây chúng ta đi đến câu hỏi chính: chúng ta nên đặt kích thước nào cho danh sách? Lựa chọn tốt nhất là cung cấp cho anh ta kích thước chính xác. Ví dụ: Trong trường hợp này, chính xác n tên phải được trả về và kết quả là một tập hợp gồm n phần tử được tạo. Tuy nhiên, giá trị chính xác của n không phải lúc nào cũng được biết. Ngay cả trong ví dụ đã cho, điều gì sẽ xảy ra nếu n=1000 và chỉ có 100 tên? Khi làm việc với các bộ sưu tập, phương pháp phổ biến nhất là gọi hàm tạo mặc định. Nếu bạn nhìn vào mã nguồn Java (phiên bản 1.6) Như bạn có thể thấy, theo mặc định, một danh sách gồm 10 phần tử được tạo . Nghĩa là, chúng ta có thể sử dụng hàm tạo mặc định một cách an toàn khi không dự định lưu trữ nhiều hơn 10 phần tử trong danh sách. Điều gì xảy ra nếu bạn cố gắng thêm phần tử thứ 11? Chà, không có gì xấu... phần tử sẽ được thêm thành công. Nhìn vào phương thức: Kích thước của mảng được kiểm soát bởi phương thức EnsureCapacity . Kích thước tăng lên 1,5 lần . Một mảng mới được tạo và các phần tử được chuyển vào mảng đó. Nếu chúng ta đặt kích thước thành 10 thì ở phần tử thứ 11:
public List getAllNames() { List names; if (/*необходимые условия выполнены*/) { names = new ArrayList (); /*заполнение списка*/ } return names; }
List names = null; List names = new ArrayList (); List names = new ArrayList (0); List names = new ArrayList (size);
public List getTopNames (int n) { List names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList (n); /*заполнение списка*/ } return names; }
names = new ArrayList ();

/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; } public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
  • kích thước thay đổi thành 10 * 3/2 + 1 = 16
  • lần tăng tiếp theo = 16 * 3/2 + 1 = 25
  • lần tăng tiếp theo = 25 * 3/2 + 1 = 39, v.v.
Trong trường hợp có 100 phần tử, JVM sẽ cần tạo một mảng mới nhiều lần và sao chép các phần tử vào đó. Khi tính đến điều này, nếu có giả định về kích thước yêu cầu của mảng, tốt hơn là bạn nên đặt dung lượng ban đầu gần với kích thước đó. Dưới đây là một số hướng dẫn hành động:
  1. Chỉ tạo một bộ sưu tập khi bạn cần , nếu không thì hãy khởi tạo nó thành null hoặc sử dụng Collections.EMPTY_LIST .
  2. Nếu bạn biết chính xác kích thước cần thiết , hãy chỉ định kích thước đó trong hàm tạo bộ sưu tập.
  3. Nếu bạn chắc chắn rằng số phần tử sẽ không vượt quá 10 , hãy sử dụng hàm tạo mặc định.
  4. Rủi ro liên quan đến việc tạo bộ sưu tập có kích thước bằng 0 là tần suất tạo mảng mới và sao chép dữ liệu có thể cao hơn. Bạn cần suy nghĩ thật kỹ xem liệu việc sử dụng bộ sưu tập có kích thước bằng 0 có mang lại nhiều lợi ích hay không .
  5. Nếu bạn đã khởi tạo một bộ sưu tập quá lớn ở đầu phương thức và muốn giảm bớt nó thì có phương thức TrimToSize() .
Tất nhiên, những nguyên tắc này áp dụng khi làm việc với các bộ sưu tập dựa trên mảng và không có nguyên tắc nào trong số này có ý nghĩa trong trường hợp danh sách được liên kết. Trên thực tế, những vấn đề này khó có thể trở thành kẻ giết chết chương trình, nhưng nếu có cơ hội để làm tốt hơn một chút thì tại sao không tận dụng nó. Bạn có lời khuyên hữu ích nào khác không? Bạn đã tìm ra cách để làm cho mọi thứ hoạt động tốt hơn chưa? Hay tất cả điều này là không cần thiết? Bạn nghĩ sao?
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION