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
{
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();
}
}
}
Artykuły z kategorii
Aktualności
- Word usuwa pliki zamiast je zapisać! Microsoft przyznaje się do błędu i sugeruje rozwiązanie
- Aktualizacja z poprawkami do PowerToys 0.85.1
- Teraz możemy udostępniać hotspot 6GHz w Windows 11
- Konkurencja protestuje. Microsoft Edge ma być obięty regulacją DMA
- Nowości wizualne w Microsoft Teams. Tym darmowym!
- Microsoft zakłada nowe studio "Halo Studios" i porzuca silnik Slipspace
- Nowa aktualizacja Windows 11 24H2 i kwantowy Doom! To był tydzień z Microsoft 336
- Microsoft wreszcie doda tę funkcję do "Narzędzia wycinanie"
Artykuły
- Chmura dla firm - jak sektor MŚP korzysta z rozwiązań chmurowych?
- Bezpieczeństwo w sieci. 10 porad, jak chronić swoje dane w Internecie
- Bezpieczne płatności w Internecie - jakie są i na co uważać przy zakupach online?
- Co nowego w Microsoft 365? Podsumowanie zmian z września 2024
- Dlaczego kody do The Sims są nieodłączną częścią tej gry?
- Cloud computing - czym jest i dlaczego warto się nim zainteresować?
- Microsoft Office 2024 już dostępny w przedsprzedaży! Co nowego?
- 5 wskazówek, jak dbać o baterię w laptopie