2012-01-04 5 views
6

Jeśli mamy następującą zmienną deklarację:Dlaczego wstawianie listy kończy się niepowodzeniem, jeśli w konstrukcji podano wystarczającą wielkość?

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

Dlaczego to:

list.insert(2, 3); 

niepowodzeniem z powodu następującego błędu:

Index must be within the bounds of the List. 

Jaki jest sens zapewniając początkowy rozmiar?

+4

Nie można wstawić w pozycji 2, jeśli pozycje 0 i 1 nie są jeszcze wypełnione –

+0

Jak słusznie wskazał, pojemność nie jest taki sam jak rozmiar . Napisz Count do konsoli przed wywołaniem Insert, lista zawiera mniej niż 3 elementy, więc wstawienie nowej wartości na trzecią pozycję kończy się niepowodzeniem. –

Odpowiedz

8

Cały początkowy rozmiar to provide a hint to the implementation to have at least a given capacity. Nie tworzy listy wypełnionej domyślnymi wpisami N; Kopalnia nacisk:

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

Jeśli nadal poprzez wejścia MSDN do sekcji Uwagi, przekonasz się dlaczego to przeciążenie konstruktora jest (ponownie, moje podkreślenie):

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> .

W krótkim List<T>.Count jest nie jest taki sam jak List<T>.Capacity ("Jeśli liczba przekracza pojemność podczas dodawania elementów, zwiększa się pojemność ...").

pojawić się wyjątek, ponieważ lista tylko logicznie zawiera elementy, które dodają, zmieniając pojemność nie zmienia liczbę elementów logicznie przechowywanych. Jeśli było ustawić List<T>.Capacity do mniej niż List<T>.Count możemy przetestować to zachowanie będzie inny kierunek

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

Aby utworzyć zachowanie może szukasz:

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

Następnie, czego używa ta podpowiedź, jeśli nie utworzyć początkowego sklepu kopii zapasowych? – Erix

+0

'List ' nie * ma * używać tablicy dla magazynu kopii zapasowej, może użyć 'LinkedList ' lub innej implementacji. Wszystko, co robisz, polega na informowaniu go * oczekiwaniami * 'N' w nadziei, że wpływ na wydajność rozszerzenia listy o tyle wpisów będzie znikomy. – user7116

+0

Oznacza to po prostu, że może otrzymać 5 elementów, zanim obiekt List będzie musiał się rozwinąć. To optymalizacja wydajności. – Tormod

0

Ponieważ zakłada, że ​​wkładka na liście znajduje się już tyle pozycji - pojemność to nie to samo, co rozmiar. Inicjowanie listy o określonej pojemności powoduje jedynie ustawienie rozmiaru wewnętrznej tablicy - jest to optymalizacja, aby zapobiec zmianie rozmiaru tablicy, gdy znasz liczbę elementów, które zamierzasz wstawiać.

0

Konstruktor List (int) określa początkową pojemność listy. Nie określa liczby początkowych elementów. Po zbudowaniu lista jest pusta, więc każde wstawienie może być wykonane tylko na indeksie 0.

2

Rozmiar w konstruktorze mówi ile zaalokować dla tablicy tła - jest jednak nadal pusty (po prostu: pusty z pewna ilość początkowej przestrzeni).

Możesz wstawić do używanej części listy lub na końcu.

2

Wewnętrznie List(T) jest realizowany za pomocą tablicy w tle. Kiedy zainicjujesz listę w ten sposób, ustawiasz tylko rozmiar podstawowej tablicy, która zmienia się wraz ze wzrostem listy. W ten sposób inicjujesz początkową pojemność. To nie znaczy, że twoja lista ma tak wiele elementów.

Dodaje się elementy do listy, najpierw inicjując ją, a następnie dodając do niej elementy za pomocą .Add(item).

0

Początkowy rozmiar służy początkowo do określenia rozmiaru wewnętrznej tablicy.

Po wstawieniu elementów do listy przechowuje je w tablicy. Gdy tablica jest pełna, tworzy nową tablicę podwójnego rozmiaru i kopiuje wszystkie elementy. Jeśli masz pomysł, że zamierzasz umieścić 5000 elementów, będziesz chciał podać tę podpowiedź, aby nie kończyło się na zmianie rozmiaru/kopiowania tablicy.

Początkowy rozmiar wynosi , a nie oznacza, że ​​na liście znajdują się dowolne pozycje.

0

Dzieje się tak dlatego, że liczba całkowita określona w konstruktorze to kwota, którą może przechowywać List. Po dodaniu pozycji lista jest automatycznie zwiększana. Zmiana rozmiaru jest unikana, gdy określasz pojemność początkową odpowiadającą liczbie elementów, które chcesz dodać.

Jednak nadal trzeba użyć metody Dodaj, aby dodać nowe elementy.

Zobacz remarks section in the documentation

Powiązane problemy