1. ArrayListCấu trúc như thế nào

ArrayListlà lớp Java được sử dụng phổ biến nhất để lưu trữ các phần tử. Vậy nó ArrayListhoạt động như thế nào và tại sao mọi người lại thích nó đến vậy?

Cấu trúc của ArrayListlà đơn giản và khéo léo. Mỗi ArrayListđối tượng chứa hai trường:

  • Một mảng các phần tử
  • Một sizebiến, lưu trữ số phần tử trong danh sách

Bên trong, một ArrayListđối tượng chứa một mảng bình thường nhất! Nhưng đó không phải là tất cả. Ngoài ra còn có một biến kích thước lưu trữ độ dài của danh sách. Đây là cách nó hoạt động:

Ban đầu, độ dài của mảng bên trong danh sách là 10. Và sizebiến là 0.

Nếu bạn thêm một phần tử vào danh sách, nó sẽ được lưu trữ ở ô thứ 0 của mảng và sizesẽ tăng lên 1.

Nếu bạn thêm một phần tử nữa, nó sẽ được lưu trữ trong ô đầu tiên và sizesẽ lại tăng thêm 1 và bằng hai.

Nếu bạn thêm một phần tử khác khi không còn khoảng trống trong mảng, thì điều sau đây sẽ xảy ra trong add()phương thức:

  1. Một mảng mới được tạo ra có độ dài gấp rưỡi mảng trước đó
  2. Tất cả các phần tử của mảng cũ được sao chép vào mảng mới.
  3. Trong ArrayListđối tượng, tham chiếu đến mảng mới sẽ thay thế tham chiếu đến mảng cũ .
  4. Phần tử đã truyền được lưu vào ô thứ 10 của mảng mới.
  5. Biến kích thước tăng thêm 1 và bây giờ sẽ bằng 11

Điều tương tự cũng xảy ra khi thêm (chèn) một phần tử vào giữa danh sách. Các phần tử hiện có được dịch chuyển 1 sang phải và phần tử đã truyền được ghi vào ô mới được giải phóng của mảng.

Bây giờ chúng ta sẽ xem xét các kịch bản cơ bản nhất liên quan đến danh sách:


2. Thêm một phần tử vào mộtArrayList

Hãy xem điều gì xảy ra bên trong danh sách khi các phần tử được thêm vào nó. Ngay sau khi một đối tượng ArrayList được tạo, chúng ta có một cái gì đó như thế này trong bộ nhớ:

Thêm phần tử vào ArrayList

Chúng ta có một ArrayListđối tượng chứa hai trường (hai biến): vùng chứa ( datamảng) và số phần tử được lưu trữ ( size). Biến datalưu trữ một tham chiếu đến một vùng chứa (mảng) có thể lưu trữ 10 phần tử.

Nếu chúng ta quyết định thêm số 5 vào mảng, chúng ta sẽ có được hình ảnh sau:

Thêm phần tử vào ArrayList 2

Mảng hiện lưu trữ phần tử 5 và size == 1.

Nếu ai đó gọi size()phương thức trên ArrayListđối tượng của chúng ta bây giờ, giá trị trả về sẽ là số lượng phần tử được lưu trữ trong danh sách: 1. Số lượng phần tử trong danh sách không giống như khả năng lưu trữ của mảng.

Dung lượng lưu trữ hiện tại cũng như bản thân mảng sẽ không bao giờ có thể truy cập (hiển thị) bên ngoài đối ArrayListtượng. Đây là và sẽ luôn là ArrayListdữ liệu nội bộ của.

Hãy thêm 7 số nữa vào danh sách: 10, 20, 30, 40, 50, 60, 70.

Bây giờ bộ nhớ sẽ trông như thế này:

Thêm phần tử vào ArrayList

Nếu bạn gọi size()phương thức bây giờ, nó sẽ trả về số 8, là số phần tử mới trong danh sách. Giá trị này không liên quan gì đến kích thước của mảng bên trong.

Quan trọng:

Có một sự đơn giản hóa quá mức trong bức tranh này.

Lớp ArrayListkhông thể lưu trữ các kiểu nguyên thủy, vì vậy nó sử dụng Integerkiểu thay vì int. Vùng chứa không trực tiếp lưu trữ các giá trị {5, 10, 20, 30, 40, 50, 60, 70} mà thay vào đó là các tham chiếu đến Integercác đối tượng. Tất cả các ô trống trong kho chứa null.



3. Tăng độ dài của danh sách

Chúng ta hãy xem điều gì xảy ra bên trong một danh sách khi không còn ô trống nào trong mảng bên trong của nó.

Giả sử chúng ta có một danh sách gồm 10 phần tử:

Tăng độ dài của danh sách

Chúng tôi quyết định thêm số 100 vào nó. Đây là những gì xảy ra trong add()phương pháp:

Bước 1 — Tạo một mảng mới:

Tăng độ dài của danh sách 2

Bước 2 — Sao chép tất cả các phần tử từ mảng cũ sang mảng mới:

Tăng độ dài của danh sách 2

Bước 3 — Thay thế mảng cũ (thay đổi tham chiếu đến ArrayListmảng bên trong của đối tượng):

Tăng độ dài của danh sách 3

Bước 4 — Thêm số mới, đây là số mà chúng tôi đã nỗ lực rất nhiều để hoàn thành:

Tăng độ dài của danh sách 4