Zamknij komunikat

Nowy Office 2013
Do góry Skomentuj

16. Kolekcje

16. Kolekcje

Daniel Celeda
23 maja 2006
176 324
Odsłony
Daniel Celeda
23 maja 2006
176 324
Odsłony

Wiemy już do czego służą tablice. Czas poznać ich bliskich znajomych – kolekcje. Przestrzenią nazw, której będziemy musieli użyć jest „System.Collections”. Najbardziej znaną i najczęściej stosowaną kolekcją jest „ArrayList”. Jest to lista, w której tak jak w tablicy możemy przechowywać wiele elementów, jednak jest łatwiejsza w obsłudze.

Czemu więc używać zwykłych tablic?

Mają one kilka zalet, których nie posiada „ArrayList”.
Po pierwsze, podczas deklarowania tablicy określamy jakiego typu będą elementy w niej przechowywane. Dzięki tej deklaracji unikamy błędów już na etapie kompilacji polegających na dodawaniu do tablicy elementu o innym typie niż się spodziewaliśmy (kompilator wygeneruje błąd). Dodatkowo tablice działają szybciej niż „ArrayList”.

Kiedy więc używać kolekcji?

Kolekcje dają nam większa swobodę kosztem wydajności. Nie musimy ustalać rozmiaru listy tak jak to się robi w tablicach. Po prostu dodajemy bądź usuwamy kolejne elementy. „ArrayList” posiada wiele metod, które upraszczają jej obsługę oraz udostępniają dodatkową funkcjonalność. W poprzednim ćwiczeniu tworzyliśmy tablicę wypełnioną liczbami a następnie sortowaliśmy je. Używając „ArrayListy” sortować możemy za pomocą metody „Sort()”. Elementy dodajemy do kolekcji wykonując metodę „Add()”. W tym momencie kolekcja dodaje referencję do tego elementu traktując go jak obiekt klasy „object”.

using System;
using System.Collections;
 
namespace Kolekcje
{
class Program
{
static void Main(string[] args)
{
ArrayList lista = new ArrayList();
lista.Add(2);
lista.Add(11);
lista.Add(-2);
lista.Add(4);
 
Console.Write("Elementy nieposortowane: ");
for (int i = 0; i < 4; i++)
{
Console.Write(lista[i] + " ");
}
 
lista.Sort();
Console.Write("\nElementy posortowane: ");
for (int i = 0; i < 4; i++)
{
Console.Write(lista[i] + " ");
}
 
 
Console.ReadKey();
}
}

Wynik:

W następnym programie spróbujemy na liście umieścić elementy będące instancjami klasy, którą sami stworzymy.
Najpierw napiszmy program, w którym umieścimy dwa obiekty naszej klasy pomocniczej na liście, a następnie spróbujemy pobrać te elementy i bez rzutowania dostać się do zmiennej „Liczba”.

using System;
using System.Collections;
 
namespace Kolekcje
{
class Element
{
public int Liczba;
 
public Element(int liczba)
{
this.Liczba = liczba;
}
}
 
class Program
{
static void Main(string[] args)
{
Element element_1 = new Element(10);
Element element_2 = new Element(20);
 
ArrayList lista = new ArrayList();
 
lista.Add(element_1);
lista.Add(element_2);
 
int nowaZmienna = lista[0].Liczba;
 
Console.ReadKey();
}
}
}

Powyższy program nie skompiluje się, ponieważ po pobraniu elementu z listy nie zrzutowaliśmy go na typ „KlasaPomocnicza”. Element więc jest traktowany jako instancja klasy „object”, która nie posiada zmiennej „Liczba”.

Error 1 'object' does not contain a definition for 'Liczba'

Poniżej poprawnie działający program, wykonujący rzutowanie.

using System;
using System.Collections;
 
namespace Kolekcje
{
class Element
{
public int Liczba;
 
public Element(int liczba)
{
this.Liczba = liczba;
}
}
 
class Program
{
static void Main(string[] args)
{
Element element_1 = new Element(10);
Element element_2 = new Element(20);
 
ArrayList lista = new ArrayList();
 
lista.Add(element_1);
lista.Add(element_2);
 
int nowaZmienna = ((Element)lista[0]).Liczba;
 
Console.ReadKey();
}
}
}

Kod ((Element)lista[0]).Liczba najpierw wykonuje rzutowanie elementu o indeksie „0” na typ „Element”, a następnie pobierana jest wartość zmiennej „Liczba”. Nawiasy określają kolejność wykonania operacji. W przypadku ich braku (Element)lista[0].Liczba kompilator chce rzutować nie element „lista[0]” lecz zmienną „Liczba”, a ponieważ w tym momencie element jest traktowany jako obiekt klasy „object”, wygenerowany zostanie błąd ponieważ klasa „object” nie posiada zmiennej „Liczba”.

Napiszmy teraz program, w którym przechowywać na liście oraz w tablic będziemy obiekty klasy „Element”.

using System;
using System.Collections;
 
namespace Kolekcje
{
class Element
{
public int Liczba;
 
public Element(int liczba)
{
this.Liczba = liczba;
}
}
 
class Program
{
static void Main(string[] args)
{
Element[] tablica = new Element[2];
tablica[0] = new Element(10);
tablica[1] = new Element(20);
 
ArrayList lista = new ArrayList(tablica);
 
Console.Write("Elementy na liście: ");
for (int i = 0; i < lista.Count; i++)
{
int liczba = ((Element)lista[i]).Liczba;
Console.Write(liczba + " ");
}
 
Element nowyElement = new Element(123);
lista.Insert(1, nowyElement);
Console.Write("\nElementy na liście: ");
for (int i = 0; i < lista.Count; i++)
{
int liczba = ((Element)lista[i]).Liczba;
Console.Write(liczba + " ");
}
 
lista.RemoveAt(0);
Console.Write("\nElementy na liście: ");
for (int i = 0; i < lista.Count; i++)
{
int liczba = ((Element)lista[i]).Liczba;
Console.Write(liczba + " ");
}
 
Console.ReadKey();
}
}
}

Najpierw zdefiniowaliśmy sobie naszą klasę. Następnie stworzyliśmy tablicę dwuelementową i dodaliśmy do niej dwa obiekty. Posiadając wypełnioną tablicę, przekazaliśmy ją jako parametr do konstruktora „ArrayListy” i stworzyliśmy nową kolekcję na podstawie elementów znajdujących się w tablicy.
Metoda „Insert()” umieszcza element w kolekcji. Jako parametry podajemy indeks, który określa nam miejsce w kolekcji, w które chcemy wstawić element oraz drugi parametr to wstawiany obiekt.
Zmienna „Count” określa ile elementów zawiera lista, więc dzięki niej możemy użyć pętli „for” w celu wypisania wszystkich elementów.
Jeśli chcemy usunąć jakiś element znając jego indeks (miejsce które zajmuje w kolekcji) możemy użyć metody „RemoveAt()”. Jako parametr podajemy liczbę całkowitą będącą indeksem.

ArrayList” posiada znacznie więcej metod niż przedstawione w tym artykule. Są one dobrze opisane w MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcollectionsarraylistclasstopic.asp), tak więc zachęcam do zapoznania się z nimi. Przestrzeń nazw „System.Collections” zawiera jeszcze kilka rodzajów kolekcji, jednak ograniczone ramy tego kursu nie pozwalają na ich przedstawienie. Jedną z ciekawszych jest „Hashtable”, której działanie, przy większej ilości elementów, jest znacznie szybsze niż „ArrayListy”.

Pętla „foreach”.

Poznaliśmy już tablice oraz kolekcję, więc jesteśmy już w stanie zrozumieć działanie pętli „foreach”. Nie omawiałem jej w temacie poświęconym instrukcjom iteracyjnym, ponieważ jej działanie opiera się na iterowaniu po elementach znajdujących się w jakimś elemencie złożonym (np. tablicy). Dla uproszczenia będę mówił o kolekcjach. Jej składnia wygląda następująco:

foreach(typ tymczasowyElement in kolekcja)
{
//ciało pętli
}

Zacznijmy od tego, że po słówku „in” w miejsce słowa „kolekcja” należy wstawić kolekcję po której chcemy iterować (dostać się do elementów znajdujących się w danej kolekcji). Zamiast „typ” piszemy nazwę klasy, której to instancje znajdują się w kolekcji. Natomiast „tymczasowyElement” to element, który pobieramy na czas trwania jednej iteracji. Ponieważ w kolekcjach elementy przechowywane są jako instancje klasy „object”, nie moglibyśmy używać składowych (metod, zmiennych itd.) obiektów, które znajdują się w kolekcji. Podanie typu (w miejscu „typ”) powoduje, że każdy element w poszczególnej iteracji jest rzutowany na ten typ.
Przykład:

using System;
using System.Collections;
 
namespace Kolekcje
{
class Element
{
public int Liczba;
 
public Element(int liczba)
{
this.Liczba = liczba;
}
}
 
class Program
{
static void Main(string[] args)
{
Element element_1 = new Element(10);
Element element_2 = new Element(20);
Element element_3 = new Element(30);
 
ArrayList lista = new ArrayList();
 
lista.Add(element_1);
lista.Add(element_2);
lista.Add(element_3);
 
Console.Write("Elementy: ");
foreach (Element element in lista)
{
Console.Write(element.Liczba + " ");
}
 
Console.ReadKey();
}
}

Wynik (Ctrl + F5):

Ćwiczenie.

Napisać program pobierający pięć liczb od użytkownika i dodający je do „ArrayListy”. Następnie program usunie element o indeksie 2 oraz posortuje liczby. Należy wyszukać metodę, która zamienia kolejność elementów na odwrotną i wykonać ją na liście. Za pomocą pętli „foreach” należy wypisać wyniki po każdej ze zmian.

using System;
using System.Collections;
 
namespace Kolekcje
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList lista = new ArrayList();
 
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Podaj liczbę.");
                int liczba =  int.Parse(Console.ReadLine());
                lista.Add(liczba);
            }
 
            Console.Write("\nElementy: ");
            foreach (int liczba in lista)
            {
                Console.Write(liczba + " ");
            }
 
            lista.RemoveAt(2);
 
            Console.Write("\nElementy: ");
            foreach (int liczba in lista)
            {
                Console.Write(liczba + " ");
            }
 
            lista.Sort();
            Console.Write("\nElementy: ");
            foreach (int liczba in lista)
            {
                Console.Write(liczba + " ");
            }
 
            lista.Reverse();
            Console.Write("\nElementy: ");
            foreach (int liczba in lista)
            {
                Console.Write(liczba + " ");
            }
 
            Console.ReadKey();
        }
    }
}

Zobacz również

Komentarze

Przydałby się jakiś porządny opis najczęściej używanych kolekcji z praktycznymi przykładami. Porządny, mam na myśli, taki jak w tym przypadku ArrayList
Shreeve, 27 lipca 2006, 09:09
Troche zamotane :( class Program { static void Main(string["> args) { Element element_1 = new Element(10); Element element_2 = new Element(20); ArrayList lista = new ArrayList(); lista.Add(element_1); lista.Add(element_2); int nowaZmienna = ((Element)lista[0">).Liczba; Console.ReadKey(); } }
kostii, 24 sierpnia 2006, 14:05
Myślę, że za szybko i niedokładnie wytłumaczyłeś to rzutowanie. Jak to ma być kurs dla początkujących to zdecydowanie źle ci to wyszło !!!
phoobosss, 3 września 2006, 15:53
Dlaczego autor nie uzywa wciec?
., 18 czerwca 2007, 16:21
poprzednie 15 dzialow bylo napisane calkiem jasno i przejrzyscie, ale tu sie troche pogubilem, za malo napisales o tym rzutowaniu i dla poczatkujacych to nie starcza :/
bob_best, 27 lipca 2007, 12:42
Czemu tu nie ma tabulatorów ????
Karolus, 4 listopada 2007, 09:47
"public Element(int liczba) { this.Liczba = liczba; }" A nie jest przypadkiem tak, że C# odróżnia małe litery od dużych... po co w takim razie słówko this? Nie powinno być: "Liczba = liczba;" w konstruktorze klasy?
Kot-ek, 19 listopada 2007, 11:11
W początkowych rozdziałach kursu ktoś nad nim czuwał: dodawał przecinki na czerwono, komentarze podpisane literką J... a gdzie ta osoba jest teraz? Czytając pierwszy raz w ogóle nie zrozumiałem o co chodzi w zdaniu: "Napiszmy teraz program, w którym przechowywać na liście oraz w tablic będziemy obiekty klasy „Element”.". Musiałem się na dłużej zatrzymać, żeby zrozumieć "co poeta miał na myśli"... chyba takie zdanie: Napiszmy teraz program, w którym przechowywać będziemy na liście oraz w tablicy obiekty klasy „Element”
Kot-ek, 19 listopada 2007, 11:20
Może wiecie jak się przeciąża operatory w C#??? BO po co mi sort skoro nie moge przeciążyć
michalos, 23 listopada 2007, 22:32
zamiast: *** for (int i = 0; i < 4; i++) *** lepszym rozwiązaniem byłoby wykorzystanie własności: Count z klasy ArrayList, zwracającej (int) liczbę przechowywanych elementów czyli: *** for (int i = 0; i < lista.Count; i++) *** Aby w przypadku większej liczby elementów nie zastanawiać się nad ilością przechowywanych elementów w liście.
riiich, 19 grudnia 2007, 01:17
hm bardzo pieknie wszystko wytlumaczone, az o momentu KOLEKCJI, czyli rozdzialu 16... tragedia... ; napiszemy program ... ale on sie ni wykona; napiszmy program ale ten tez sie nie wykona; napiszmy program i ten sie wykona ... troche to dziwne bo powinno chyba odrazu sie kogos uczyc robic program dobrze, bo tak mozna przyswoic zla wiedze ;-)
HideYoshi, 17 stycznia 2008, 17:52
Yoshi nie da nauczyć kogoś pisać żeby nie robić błędów trzeba się z nimi oswajać i wiedzieć gdzie szukać rozwiązania... skoro nie zrozumiałeś rzutowania przeczytaj jeszcze raz.
graf , 21 lutego 2008, 03:09
+ Świetny kurs, przystępnie napisane przykłady - Podział na strony troche utrudnia czytanie --- www.polishwords.com.pl
Tomaszs, 8 marca 2008, 14:57
nie rozumiecie kolekcji, bo nie macie podstaw z innych języków... nie zrozumiecie dobrodziejstw c# bez poznania np.c++ i standard template library... bez asemblera nie zrozumiecie dokladnie jak to wszystko dziala... ale jak chociaz troche lizniecie to moze kiedys wezmiecie sie i za te prawdziw e podstawy
slimaq, 13 czerwca 2008, 02:42
@slimaq: Zgadzam sie że nie znając C++, bedzie wam cięszko zrozumieć kolekcji, ale po co komu tu jest potrzebny asembler? Ja go nie znam i jakoś rozumie to:P
camillos, 8 lipca 2008, 10:42
Bez C++ to niekoniecznie... Kolekcje są w C++, w C# i w wielu innych językach, tu nie chodzi o implementację w konkretnym języku, ale raczej pewne minimalne choćby doświadczenie w programowaniu. Do Hello World nie trzeba kolekcji. Zrozumieć można je, kiedy okazują się przydatne przy programowaniu czegoś tam i się je wykorzystuje. Niezależnie od języka. Natomiast co do asma - "jak to wszystko działa", wszystko, nie konkretnie kolekcje. Ale oczywiście asm (na szczęście?) nie jest konieczny do programowania i bez jego znajomości można sobie bez problemu dać radę z niemal wszystkim. Oczywiście to tylko moja subiektywna, swobodnie wyrażona, z pewnością nie pozbawiona błędnych podstaw, opinia. Pozdrawiam.
losiu99, 6 sierpnia 2008, 17:01
Fajny kurs i wogóle, ale żeby usunąć 2 element listy powinno chyba być RemoveAt(1) bo zaczyna się indeks od zera?
Piotrek, 25 września 2008, 09:46
No z tym asemblerem to troche przesada, nie musisz wiedziec dokaldnie jak dziala skrzynia biegow zeby przezucic bieg. Srodowiska takie jak .NET (C#) czy Java powstaly zeby nie trzeba bylo sie "babrac" w asemblera aczkolwiek tytulem rozszerzania swojej wiedzy i poznawania podstaw programowania uwazam, ze warto chociaz poczytac o co w asm chodzi aczkolwiek troche nijak sie to ma do programowania obiektowego. C++ znam calkiem niezle mysle wobec czego nie mam problemu z poznawaniem C# ale bez doswiadczenia ciezko jest przez ten rozdzial przerbnac, z drugiej strony kolekcje (czy tez listy) to w ogole temat, ktory dla poczatkujacego nie bedzie prosty. Na pocieszenie dodam, ze w C++ jest i tak duuuzo trudniej :)
Push-up, 14 października 2008, 15:04
ale tylko wiedząc jak skrzynia działa zrobisz ruch optymalnie! Jak poznacie asma - inne języki będziecie nie tyle rozumieć, co je "widzieć". Jak wiesz jak to działa to łatwiej rozwiązujesz nietypowe problemy. Bo co innego zrozumieć kurs a co innego rozwiązywać problemy laików któzy każą Ci napisać soft "ale Panie, żeby to robiło tak-a-tak!"
Co nie, Slimaq?
 
Count() - nawiasy! To jest funkcja.

hubapiet, 26 października 2008, 23:14
??? w C++ nie ma kolekcji! jest tylko stos/sterta/kolejka z STL(bibl. standarddowej) - C# łączy to wszystko w nieprzenośnym języku, ale jest to przyjemne i zrozumiałe. W sumioe znajomość C++ (lub czegoś innego) jest wymagana aby zrozumieć zaawansowane konstrukcje(tzn. za pierwszym razem) - nieoznacza to że C# jest trudniejszy od C++ - wręcz przeciwnie. Poza tym: KOGO TAK PORĄBAŁO ABY TWIERDZIĆ ŻE ASMA JEST POTRZEBNY? Do rozwiązywania problemów uzywa się logiki...

jahara, 8 stycznia 2009, 19:26
lista.Sort();  wszystko fajnie jezeli w kolekcji masz wartosci int, co sie stanie jesli tam sa obiekty klasy z jedna zmienna tez typu int:)

borcha, 24 marca 2009, 21:32
Jak ktoś ma problem z rzutowaniem to mimo wszystko proponuję przerobić tą lekcję do końca, przerobić 17 (typy generyczne) i wrócić do kolekcji. Na pewno wiele się wyjaśni.

camileq, 7 maja 2009, 22:54
borcha - wtedy trzeba tworzyc klase implementujaca cos w stylu
Comparable

tomek, 6 lipca 2009, 23:07
""object" does not contain a definition for "Liczba" and no extension method "Liczba" accepting a first argument of type "object" could be found (are you missing a using directive or an assembly reference?) "
 
uruchamiam pod net#3.0 i oczywiscie jestem laikiem zeby blad samemu naprawic

nie dziaba, 21 sierpnia 2009, 13:18
eh
umieszczanie kodu w stylu "ukazal im sie las"
a na nastepnej stronie " ...krzyzy"
spowodowalo to ze powyzszy koment jest juz bez znaczenia :)
na nastepnej stronie jest dzialajacy (chyba program)
 
ogolnie slaby artykul,zamieszany, 3 razy czytam 3 strony i wciaz nie wiem o co chodzi,podzielam zdanie reszty, do tej pory szlo gladko teraz nie wiadomo o co kaman

juz dziaba, 21 sierpnia 2009, 13:25
Przystepne, mi duzo pomogło.
Skoczek, 5 stycznia 2011, 11:22
ci ktorzy maja problem z ta lekcja proponuje dodatkowo przeczytac http://www.altcontroldelete.pl/artykuly/operacje-na-kolekcjach-w-c-/ oraz nastepny rozdzial - duzo sie wyjasni
Rolo, 12 stycznia 2011, 12:25
Przyłączam się do reszty... kolekcje okey to coś na kształt tablic, ale po cholere wrzucać tam obiekty??!! Co mi to da? Jak wykorzystam to w praktyce...?
Piotr, 29 października 2012, 13:51
Witajcie, zrozumiałem ten temat pomimo że jest mało przystępnie opisany. Polecem ten art.: http://www.---- Pozdro ziomasy heh
Piotr, 30 października 2012, 21:28
ogólnie do 15 szło łatwo na ten temat musiałem wziąć sobei kafke ;p
adrianwoo, 7 grudnia 2012, 13:03
Autor niepotrzebnie tak zamieszał. Spokojnie wystarczyłby pierwszy i ostatni przykład, aby mieć ogólny pogląd n.t. kolekcji. Osoby chcące poszerzyć swoją wiedzę powinny odwiedzić stronę: http://msdn.microsoft.com/pl-pl/library/ybcx56wz.aspx
Piter, 19 kwietnia 2014, 11:01
"Powyższy program nie skompiluje się, ponieważ po pobraniu elementu z listy nie zrzutowaliśmy go na typ „KlasaPomocnicza”." Powinno być "na typ "Element"".
CShark, 8 lipca 2015, 11:46
using System; using System.Collections; class Program { static void Main() { int i; ArrayList lista = new ArrayList(); for (i = 0; i < 5; i++) { lista.Add(int.Parse(System.Console.ReadLine())); } System.Console.WriteLine("\n "); lista.RemoveAt(2); lista.Sort(); lista.Reverse(); foreach (int element in lista) { System.Console.WriteLine(element + " "); } System.Console.ReadKey(); } }
zwięzły, 23 września 2015, 02:08

Dodaj swój komentarz

Zasady publikacji komentarzyZasady publikacji komentarzy

Redakcja CentrumXP.pl nie odpowiada za treść komentarzy publikowanych na stronach Portalu
i zastrzega sobie prawo do usuwania wypowiedzi, które:

  • zawierają słowa wulgarne, obraźliwe, prowokujące i inne naruszające dobre obyczaje;
  • są jedynie próbami reklamowania stron internetowych (spamowanie poprzez umieszczanie linków);
  • przyczyniają się do złamania prawa bądź warunków licencyjnych oprogramowania (cracki, seriale, torrenty itp.);
  • zawierają dane osobowe, teleadresowe, adresy mailowe lub numery GG;
  • merytorycznie nie wnoszą nic do dyskusji lub nie mają związku z tematem komentowanego newsa, artykułu bądź pliku.