Array versus List: When to use which?

MyClass[] array;
List<MyClass> list;

Jakie są scenariusze, gdy jeden jest lepszy od drugiego? I dlaczego?

Author: nawfal, 2009-01-12

14 answers

W rzeczywistości rzadko zdarza się, że chcesz użyć tablicy. Zdecydowanie używaj List<T> za każdym razem, gdy chcesz dodać / usunąć dane, ponieważ zmiana rozmiaru tablic jest kosztowna. Jeśli wiesz, że dane mają stałą długość i chcesz mikrooptymalizować z jakiegoś bardzo konkretnego powodu (po benchmarkingu), to tablica może być przydatna.

List<T> oferuje dużo więcej funkcjonalności niż tablica (chociaż LINQ trochę ją wyrównuje) i prawie zawsze jest właściwym wyborem. Z wyjątkiem params argumenty, oczywiście. ;- P

Jako licznik - List<T> jest jednowymiarowy; gdzie-jak masz prostokątne (etc) tablice jak int[,] lub string[,,] - ale są inne sposoby modelowania takich danych (jeśli potrzebujesz) w modelu obiektowym.

Zobacz też:

To powiedziawszy, wykonuję wiele użycia tablic w moim protobuf-net projekcie; całkowicie za wykonanie:

    Kodowanie jest bardzo proste, więc kodowanie jest bardzo ważne dla kodowania.]}
  • używam lokalnego bufora rolling byte[], który wypełniam przed wysłaniem do podstawowego strumienia (i v. v.); szybciej niż BufferedStream etc;
  • wewnętrznie używa modelu obiektów opartego na tablicy (Foo[] zamiast List<Foo>), Ponieważ rozmiar jest ustalany po zbudowaniu i musi być bardzo szybki.

Ale to zdecydowanie wyjątek; dla ogólnego przetwarzanie linii biznesowych, a List<T> wygrywa za każdym razem.

 471
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:26

Naprawdę tylko odpowiadam na dodanie linka, o którym dziwi mnie, że jeszcze nie wspomniano: wpis na blogu Erica Lipperta na " Tablice uważane za nieco szkodliwe."

Z tytułu można wywnioskować, że sugeruje użycie zbiorów wszędzie tam, gdzie jest to praktyczne - ale jak słusznie zauważa Marc, jest wiele miejsc, w których tablica jest naprawdę jedynym praktycznym rozwiązaniem.

 107
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-12 08:26:44

Użyj tablicy, gdy masz do czynienia z danymi, które są:

  • stały rozmiar, lub mało prawdopodobne, aby urosły dużo
  • odpowiednio duże (ponad 10, 50, 100 elementów, w zależności od algorytmu)
  • będziesz robił wiele indeksowania do niego, tzn. wiesz, że często będziesz chciał trzeci element, albo piąty, czy cokolwiek innego.

Użyj listy dla:

  • listy danych o zmiennej długości
  • które są najczęściej używane jako stos lub Kolejka lub wymagają iteracji w jego całość
  • Jeśli nie chcesz pisać wyrażenia, aby uzyskać ostateczny rozmiar tablicy dla deklaracji i nie chcesz marnotrawnie wybierać dużej liczby

Użyj hashmapy dla:

  • listy danych o zmiennej długości
  • które muszą być indeksowane jak tablica

W rzeczywistości, będziesz chciał listę lub hashmap prawie cały czas. Następnym razem, gdy wybierzesz strukturę danych, zastanów się, co musi zrobić dobrze dla Ciebie(lub Twojego kodu). Następnie wybierz coś na tej podstawie. W razie wątpliwości wybierz coś tak ogólnego, jak to możliwe, tj. interfejs, który możesz dość łatwo zastąpić implementacją. Kilka dobrych linków w innych odpowiedziach, jak również.

 43
Author: wds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-21 14:46:19

Niezależnie od innych odpowiedzi zalecających List<T>, będziesz chciał używać tablic podczas obsługi:

  • Dane Bitmapowe obrazu
  • inne niskopoziomowe struktury danych (np. protokoły sieciowe)
 17
Author: Alnitak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-12 08:16:48

Chyba, że naprawdę interesuje Cię wydajność ,a przez to mam na myśli: "dlaczego używasz. Net zamiast C++?"powinieneś trzymać się listy. Jest łatwiejszy w utrzymaniu i wykonuje całą brudną robotę, zmieniając rozmiar tablicy za kulisami. (Jeśli to konieczne, Listjest dość inteligentny w wyborze rozmiarów tablic, więc zwykle nie musi.)

 9
Author: Spencer Ruport,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-12 08:12:54

Tablice powinny być używane w preferencjach List, gdy niezmienność samej kolekcji jest częścią Umowy między klientem i dostawcą kodu (niekoniecznie niezmienność elementów w kolekcji) i gdy nie jest odpowiednia liczba.

Na przykład,

var str = "This is a string";
var strChars = str.ToCharArray();  // returns array

Jest jasne, że modyfikacja " strChars "nie zmutuje oryginalnego obiektu" str", niezależnie od znajomości bazowego typu"str" na poziomie implementacji.

Ale przypuśćmy że

var str = "This is a string";
var strChars = str.ToCharList();  // returns List<char>
strChars.Insert(0, 'X');

W tym przypadku nie jest jasne, czy metoda insert zmutuje oryginalny obiekt "str". To wymaga znajomości poziomu implementacji ciągu do tego ustalenia, co łamie projekt przez podejście umowy. W przypadku Sznurka nie jest to nic wielkiego, ale może to być coś wielkiego w prawie każdym innym przypadku. Ustawienie listy NA tylko do odczytu pomaga, ale powoduje błędy w czasie wykonywania, a nie w czasie kompilacji.

 6
Author: Herman Schoenfeld,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 01:37:08

Jeśli dokładnie wiem, ile elementów będę potrzebował, powiedzmy, że potrzebuję 5 elementów i tylko Kiedykolwiek 5 elementów, to używam tablicy. W przeciwnym razie po prostu używam listy.

 3
Author: smack0007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-12 08:37:01

W większości przypadków użycie List wystarczyłoby. List używa wewnętrznej tablicy do obsługi swoich danych i automatycznie zmienia rozmiar tablicy podczas dodawania większej liczby elementów do List niż jej bieżąca pojemność, co sprawia, że jest ona łatwiejsza w użyciu niż tablica, w której musisz wcześniej znać pojemność.

Zobacz http://msdn.microsoft.com/en-us/library/ms379570 (v=vs.80). aspx#datastructures20_1_topic5 aby uzyskać więcej informacji o listach w C # lub po prostu dekompilować System.Collections.Generic.List<T>.

Jeśli potrzebujesz danych wielowymiarowych (na przykład przy użyciu matrycy lub w programowaniu graficznym), prawdopodobnie zamiast tego wybierzesz array.

Jak zawsze, jeśli pamięć lub wydajność jest problemem, zmierz go! W przeciwnym razie możesz wprowadzać fałszywe założenia co do kodu.

 3
Author: Sune Rievers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-20 13:51:01

Inna sytuacja, o której jeszcze nie wspomniano, to sytuacja, w której będziemy mieli dużą liczbę elementów, z których każdy składa się ze stałej wiązki powiązanych, ale niezależnych zmiennych połączonych ze sobą (np. współrzędne punktu lub wierzchołki trójkąta 3d). Tablica struktur eksponowanych pól pozwoli na efektywną modyfikację jego elementów "na miejscu" - coś, co nie jest możliwe przy żadnym innym typie zbioru. Ponieważ tablica struktur trzyma swoje elementy kolejno w pamięci RAM, sekwencyjny dostęp do elementów tablicy może być bardzo szybki. W sytuacjach, gdy kod będzie musiał wykonać wiele sekwencyjnych przejść przez tablicę, tablica struktur może przewyższyć tablicę lub inny zbiór odwołań do obiektów klasy o współczynnik 2: 1; ponadto, możliwość aktualizacji elementów w miejscu może pozwolić tablicy struktur na przewyższenie jakiegokolwiek innego rodzaju zbioru struktur.

Chociaż tablice nie można zmieniać rozmiaru, nie jest trudno mieć kod przechowujący odniesienie do tablicy wraz z liczbą elementów, które są w użyciu, i zastąp tablicę większą w razie potrzeby. Alternatywnie, można łatwo napisać kod dla typu, który zachowywał się podobnie jak List<T>, ale ujawnił swój zapasowy magazyn, umożliwiając w ten sposób wypowiedzenie MyPoints.Add(nextPoint); lub MyPoints.Items[23].X += 5;. Zauważ, że ten ostatni niekoniecznie rzuci wyjątek, jeśli kod spróbuje uzyskać dostęp poza koniec listy, ale użycie byłoby koncepcyjnie podobne do List<T>.

 1
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-21 21:17:28

Listy w. Net są owijaczami nad tablicami i używają tablicy wewnętrznie. Złożoność czasowa operacji na listach jest taka sama jak w przypadku tablic, jednak istnieje trochę więcej kosztów z całą dodaną funkcjonalnością / łatwością użycia list (takich jak automatyczne zmienianie rozmiaru i metody, które pochodzą z klasą list). W zasadzie, polecam używać list we wszystkich przypadkach, chyba że istnieje przekonujący powód nie, aby to zrobić, na przykład, jeśli trzeba napisać bardzo zoptymalizowany kod, lub pracują z innym kodem zbudowanym wokół tablic.

 1
Author: iliketocode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-09 05:39:41

To całkowicie zależy od kontekstów, w których struktura danych jest potrzebna. Na przykład, jeśli tworzysz elementy, które mają być używane przez inne funkcje lub usługi, lista jest idealnym sposobem na to.

Teraz, jeśli masz listę elementów i chcesz je po prostu wyświetlić, powiedzmy, że na tablicy stron internetowych jest kontener, którego potrzebujesz użyć.

 0
Author: sajidnizami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-12 08:16:28

Zamiast porównywać cechy każdego typu danych, myślę, że najbardziej pragmatyczna odpowiedź brzmi: "różnice prawdopodobnie nie są tak ważne dla tego, co musisz osiągnąć, zwłaszcza, że oba implementują IEnumerable, więc postępuj zgodnie z popularną konwencją i używaj List, dopóki nie będziesz miał powodu, aby tego nie robić, w którym momencie prawdopodobnie będziesz miał powód do używania tablicy nad List."

Przez większość czasu w managed code będziesz chciał faworyzować Kolekcje będące tak łatwa w obsłudze, jak to tylko możliwe, przez martwienie się o mikro-optymalizacje.

 0
Author: moarboilerplate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 21:22:49

Mogą być niepopularne, ale jestem fanem tablic w projektach gier. - Szybkość iteracji może być ważna w niektórych przypadkach, foreach na tablicy ma znacznie mniej narzutu, jeśli nie robisz zbyt wiele na element - Dodawanie i usuwanie nie jest takie trudne z funkcjami pomocniczymi - Jest wolniejszy, ale w przypadkach, gdy zbudujesz go tylko raz, może to nie mieć znaczenia - W większości przypadków marnuje się mniej dodatkowej pamięci (tylko naprawdę istotne z tablicami struktur) - Nieco mniej śmieci i wskaźników i wskaźników chasing

Biorąc to pod uwagę, używam List znacznie częściej niż tablic w praktyce, ale każda z nich ma swoje miejsce.

Byłoby miło, gdyby lista, gdzie Wbudowany typ, aby mogli zoptymalizować owijarkę i wyliczyć narzut.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-15 22:16:01

Ponieważ nikt nie wspomina: MyClass[] oraz List<MyClass> oba realizują IList<MyClass>. Jeśli zastanawiasz się, który z nich przyjąć jako argument, możesz zadeklarować go jako IList<MyClass> dla wygody wywołujących. (np. Foo(IList<int> foo) można nazwać jak Foo(new[] { 1, 2, 3 }) lub Foo(new List<int> { 1, 2, 3 }))

 -1
Author: snipsnipsnip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 01:09:40