2012-01-04 30 views
6

Nếu chúng ta có khai báo biến sau đây:Tại sao danh sách chèn không thành công khi có đủ kích thước khi xây dựng?

List<int> list = new List(5); 

Tại sao thực hiện điều này:

list.insert(2, 3); 

thất bại với các lỗi sau:

Index must be within the bounds of the List. 

điểm cung cấp kích thước ban đầu là gì?

+4

Bạn không thể chèn ở vị trí thứ 2, nếu vị trí 0 và 1 chưa đầy –

+0

Như một cách chính xác chỉ ra, khả năng không giống như kích thước . Viết Count vào giao diện điều khiển trước khi gọi Insert, danh sách có ít hơn 3 mục, vì vậy chèn giá trị mới vào vị trí thứ 3 thất bại. –

Trả lời

8

Tất cả kích thước ban đầu là provide a hint to the implementation to have at least a given capacity. Nó không tạo ra một danh sách chứa đầy các mục nhập mặc định là N; tôi nhấn mạnh:

Initializes a new instance of the List<T> class that is empty and has the specified initial capacity.

Nếu bạn tiếp tục thông qua các mục nhập MSDN vào phần chú thích, bạn sẽ tìm thấy lý do tại sao tình trạng quá tải constructor này được cung cấp (một lần nữa, tôi nhấn mạnh):

The capacity of a List<T> is the number of elements that the List<T> can hold. As elements are added to a List<T> , the capacity is automatically increased as required by reallocating the internal array.

If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the List<T> .

Nói tóm lại là List<T>.Count không giống như List<T>.Capacity ("Nếu Count vượt quá Dung lượng khi thêm yếu tố, dung lượng được tăng lên ...").

Bạn nhận được ngoại lệ bởi vì danh sách chỉ logic chứa các mục mà bạn thêm, thay đổi công suất không thay đổi số lượng các mục logic lưu trữ. Nếu bạn đã thiết lập List<T>.Capacity đến dưới List<T>.Count chúng ta có thể kiểm tra hành vi này xảy ra theo một hướng khác:

Unhandled Exception: System.ArgumentOutOfRangeException: capacity was less than 
the current size. 
Parameter name: value 
    at System.Collections.Generic.List`1.set_Capacity(Int32 value) 

Để có lẽ tạo ra hành vi mà bạn đang tìm kiếm:

public static List<T> CreateDefaultList<T>(int entries) 
{ 
    return new List<T>(new T[entries]); 
} 
+0

Sau đó, nó sử dụng gợi ý đó nếu không tạo một cửa hàng sao lưu ban đầu? – Erix

+0

'Danh sách ' không * có * để sử dụng mảng cho một cửa hàng sao lưu, nó có thể sử dụng 'LinkedList ' hoặc một số triển khai khác. Tất cả những gì bạn đang làm là bảo nó * mong đợi * các mục 'N' với hy vọng rằng tác động hiệu suất của việc mở rộng danh sách để giữ nhiều mục nhập đó sẽ không đáng kể. – user7116

+0

Nó chỉ đơn giản có nghĩa là nó có thể nhận được 5 mục trước khi đối tượng List cần phát triển. Đó là một tối ưu hóa hiệu suất. – Tormod

0

Bởi vì chèn giả định rằng danh sách thực sự có nhiều mục đã được chèn vào - dung lượng không giống với kích thước. Việc khởi tạo danh sách với dung lượng đã cho chỉ cần đặt kích thước của mảng nội bộ - đó là tối ưu hóa để ngăn thay đổi kích thước mảng khi bạn biết số lượng các mục mà bạn sẽ chèn vào.

0

Trình tạo danh sách (int) chỉ định dung lượng ban đầu của danh sách. Nó không chỉ định số lượng các phần tử ban đầu. Khi xây dựng một danh sách trống, do đó, bất kỳ chèn chỉ có thể được thực hiện tại chỉ số 0.

2

Kích thước trong hàm tạo cho nó bao nhiêu để phân bổ cho mảng nền - nó vẫn còn, tuy nhiên, trống (chỉ: rỗng với một số lượng không gian ban đầu nhất định).

Bạn có thể nhập mã vào phần được sử dụng của danh sách hoặc ở cuối.

2

Nội bộ List(T) được triển khai bằng cách sử dụng một mảng trong nền. Khi bạn khởi tạo danh sách theo cách đó, bạn chỉ cần thiết lập kích thước của mảng bên dưới để thay đổi kích thước khi danh sách tăng lên. Vì vậy, bạn đang khởi tạo dung lượng ban đầu. Nó không có nghĩa là danh sách của bạn có nhiều yếu tố.

Bạn thêm các phần tử vào danh sách bằng cách khởi tạo nó lần đầu tiên và sau đó thêm các phần tử vào nó với .Add(item).

0

Kích thước ban đầu được sử dụng để biểu thị kích thước của mảng nội bộ, ban đầu.

Khi bạn chèn các mục vào Danh sách, nó lưu trữ chúng trong một mảng. Khi mảng đầy, nó tạo ra một mảng mới có kích thước gấp đôi và sao chép tất cả các mục. Nếu bạn có ý tưởng rằng bạn sẽ đặt 5000 mục, bạn sẽ muốn chỉ định gợi ý đó để nó không kết thúc làm nhiều thay đổi kích thước/sao chép mảng.

Kích thước ban đầu là không cho biết rằng có bất kỳ mục nào trong danh sách.

0

Đó là vì số nguyên bạn chỉ định trong hàm tạo là số tiền mà Danh sách có thể giữ. Khi các mục được thêm vào, danh sách sẽ tự động được tăng lên. Bạn có thể thay đổi kích thước khi bạn chỉ định dung lượng ban đầu khớp với số lượng mục bạn muốn thêm.

Tuy nhiên, bạn vẫn phải sử dụng phương thức Thêm để thêm mục mới.

Xem remarks section in the documentation

Các vấn đề liên quan