440 likes | 593 Views
Arrays and collections – nizovi i kolekcije. Nizovi i kolekcije su strukture podataka koje omogućavaju da se na efikasan način omogući programska manipulacija sa velikim brojem podataka koji predstavljaju neke grupacije koje treba tretirati kao celine
E N D
Arrays and collections – nizovi i kolekcije • Nizovi i kolekcije su strukture podataka koje omogućavaju da se na efikasan način omogući programska manipulacija sa velikim brojem podataka koji predstavljaju neke grupacije koje treba tretirati kao celine • Ove strukture omogućavaju elegantno rešavanje raznih problema koji mogu da nastanu kod rukovanja sa velikim brojem podataka • Nizovi su jednostavnije strukture podataka od kolekcija tako da će prvo nizovi biti detaljno objašnjeni
Šta je niz? • Niz je neuređena sekvenca podataka koji su svi istog tipa • Elementi niza su istog tipa i smešteni su u uzastopnim blokovima u memoriji • Niz je referentni tip podataka • Elementi niza su obeleženi numeričkim indeksom koji služi za referenciranje pojedinačnih elemenata niza • Deklaracija niza: • int[] pins; // Personal Identification Numbers • Uglaste zagrade iza tipa označavaju niz koji se zove pins • Za deklaraciju ne treba navesti broj elemenata
Niz • Preporučuje se imenovanje niza sa imenicom u množini tako da asocira na koleciju podataka • Elementi niza mogu biti kako primitivni – vrednosni tipovi, tako i složeni referentni tipovi • Nizovi su uvek referentni tipovi bez obzira da li su elementi nizova vrednosni ili referentni tipovi • Niz kao referentni tip se ponaša kao i ostali referentni tipovi • Deklarisana nizovna promenljiva nalazi se na stack-u • Mesto u memoriji za elemente niza se ne rezerviše sve dok se sa new ne kreira niz sa navedenim brojem elemenata na heap-u
Niz • Kreiranje niza na heap-u • pins = new int[4]; • Na heap-u se kreira niz od 4 elemenata tipa int koji se po default-u inicijalizuju, u ovom slučaju sa 0, ili sa null / false kod drugih tipova podataka (referenca / logički tip)
Veličina niza – broj elemenata niza • Veličina niza ne mora da bude zadata konstantom, već se može odrediti u run time-u – tokom izvršavanja programa • int size = int.Parse(Console.ReadLine()); • int[] pins = new int[size]; • Veličina niza nije u principu ograničena, a može biti i 0 što je pogodno kada se broj elemenata niza izračunava, pa se može dobiti i 0 • Mogu se kreirati i višedimenzionalni nizovi sa dva ili više indeksa • int[,] table = new int[4,6];// dvo dimenzioni niz sa 4*6=24 elementa
Inicijalizacija niza • Kada se niz kreira sa new, svi elementi niza se inicijalizuju sa podrazumevanim vrednostima u zavisnosti od tipa elemenata (0 / null / false) • Može se izvršiti i inicijalizacija niza sa drugačijim vrednostima različitim od podrazumevanih • int[] pins = new int[4]{ 9, 3, 7, 2 }; • Vrednosti za inicijalizaciju ne moraju biti konstantne • Random r = new Random(); • int[] pins = new int[4]{ r.Next() % 10, r.Next() % 10, • r.Next() % 10, r.Next() % 10 }; • System.Randomje klasa koja služi kao pseudorandom number generator
Inicijalizacija niza • int[] pins = new int[3]{ 9, 3, 7, 2 }; // compile-time error • int[] pins = new int[4]{ 9, 3, 7 }; // compile-time error • int[] pins = new int[4]{ 9, 3, 7, 2 }; // okay • Navedeni broj elemenata i navedeni broj vrednosti za inicijalizaciju moraju biti isti • New se može izostaviti: • int[] pins = { 9, 3, 7, 2 }; • Niz struktura: • Time[] schedule = { new Time(12,30), new Time(5,30) };
Implicitno zadat niz • Tip elemenata niza može biti implicitno zadat preko vrednosti za inicijalizaciju • var names = new[]{“John”, “Diana”, “James”, “Francesca”}; • Sve vrednosti moraju biti istog tipa • var bad = new[]{“John”, “Diana”, 99, 100}; • Dozvoljeno je mešati numeričke tipove koje compiler može da konvertuje i sve prebaci u tip najveće dužine – tačnosti – double u ovom slučaju • var numbers = new[]{1, 2, 3.5, 99.999};
Niz anonimnih objekata • var names = new[] { new { Name = “John”, Age = 42 }, • new { Name = “Diana”, Age = 43 }, • new { Name = “James”, Age = 15 }, • new { Name = “Francesca”, Age = 13 } }; • Sa new[] se kreira kreira niz anonimnih objekata na stack-u dok se sa ostale 4 new naredbe kreiraju anonimni objekti koji moraju svi da imaju ista polja • Pošto se promenljiva names sa leve strane implicitno deklariše sa var, nije ni potrebno da se zna tip anonimnih objekata
Pristup elementima niza • Pojedinačnim elementima niza se pristupa preko indeksa koji počinje sa nulom – prvi elemenat ima indeks 0, drugi 1, ... n-ti elemenat ima indeks n-1 • Čitanje 3. vrednosti niza: • int myPin; • myPin = pins[2]; • Upis 3. vrednosti u niz • myPin = 1645; • pins[2] = myPin;
Pristup nepostojećem elementu niza • Pokušaj pristupa elementu niza koji je van opsega elemenata, tj. kada je indeks manji od0 iliveći oddužine niza – 1, daje izuzetak IndexOutOfRangeException • try • { • int[] pins = { 9, 3, 7, 2 }; • Console.WriteLine(pins[4]); // error, the 4th and last element is at index 3 • } • catch (IndexOutOfRangeException ex) • { • ... • }
Prolazak kroz sve elemente niza • Svi nizovi nasleđuju od bazne klase System.Array u Microsoft .NET Framework-u • Property – svojstvo Length daje dužinu tj. broj elemenata niza • Ispis svih elemenata niza: • int[] pins = { 9, 3, 7, 2 }; • for (int index = 0; index < pins.Length; index++) • { • int pin = pins[index]; • Console.WriteLine(pin); • }
Prolazak kroz sve elemente niza • Druga vrsta petlje za prolazak kroz sve elemente niza je for each petlja, modifikacija for petlje • int[] pins = { 9, 3, 7, 2 }; • foreach (int pin in pins) • { • Console.WriteLine(pin); • } • Promenljiva pin uzima vrednosti svih elemenata niza i treba da bude istog tipa kao i elementi niza • Foreach petlja ne zahteva poznavanje broja elemenata niza i automatski prolazi kroz sve elemente niza
Poređenje for i foreach • Foreach petlja je pogodnija za prolazak kroz sve elemente kada je potrebno samo čitanje • For petlja se koristi kada treba pristupiti samo određenim elementima niza, ne svima • Foreach uvek ide uzlazno od 0 do n-1, ako treba ići u suprotnom smeru, koristi se običan for • Ako je potrebna vrednost index-a, koristi se for • Ako je potreban upis – dodela vrednosti elementima niza koristi se for, jer se sa foreach može samo čitati
Niz sa anonimnim objektima • var names = new[] { new { Name = “John”, Age = 42 }, • new { Name = “Diana”, Age = 43 }, • new { Name = “James”, Age = 15 }, • new { Name = “Francesca”, Age = 13 } }; • foreach (varfamilyMember in names) • { • Console.WriteLine(“Name: {0}, Age: {1}”, familyMember.Name, familyMember.Age); • }
Kopiranje nizova • Nizovi su referentni tipovi što znači da se kopiranje vrednosti promenljive svodi na kopiranje reference, tako da posle toga obe promenljive pokazuju na isti objekat na heap-u • int[] pins = { 9, 3, 7, 2 }; • int[] alias = pins; // alias and pins refer to the same array instance • Ako se na pr promeni pins[1], to se isto vidi I preko alias[1] • Ako je potrebno napraviti kopiju podataka – objekta na heap-u, mora se prethodno kreirati novi niz
Kopiranje nizova • int[] pins = { 9, 3, 7, 2 }; • int[] copy = new int[4]; • Ili još bolje ovako: • int[] copy = new int[pins.Length]; • Zatim je potrebno kopiranje vrednosti elemenata • for (int i = 0; i < copy.Length; i++) • { • copy[i] = pins[i]; • } • Može i korišćenjem CopyTo metoda klase System.Array • pins.CopyTo(copy, 0);
Kopiranje nizova • Postoji i statički metod Copy klase Array • Array.Copy(pins, copy, copy.Length); • Metod Clone ujedno kreira i kopira niz • int[] pins = { 9, 3, 7, 2 }; • int[] copy = (int[])pins.Clone(); • Metod Clone vraća Object, zbog čega je neophodan type casting (konverzija tipova) • Opisani metodi daju tzv plitku kopiju, jer ako su elementi niza reference, kopiranje se svodi na kopiju adresa, pri čemu iskopirane reference pokazuju na iste objekte kao i originalne reference
Klase kolekcije • Microsoft .NET Framework obezbeđuje još nekoliko klasa iz imenskog prostora System.Collections koje pružaju veće mogućnosti za rad sa kolekcijama podataka u odnosu na nizove • Jedna od suštinskih razlika kolekcija u odnosu na niz je da su elementi kolekcije uvek objekti, tj. referentni tipovi, nezavisno da li su sami podaci vrednosni ili referentni tipovi • To znači da čak i kada su elementi kolekcije vrednosni tipovi, konvertuju se u objekte putem boxing-a
Klase kolekcije • Elementi niza u memoriji:
Klase kolekcije • Elementi kolekcije u memoriji:
The ArrayList Collection Class • ArrayList klasa kolekcije se koristi kada su potrebne dodatne funkcionalnosti manipulacije sa elementima kolekcije koje nizovi ne omogućavaju • Promena dužine – broja elemenata kolekcije. Ako se koriste nizovi neophodno je kreirati novi niz duži nego prethodni i iskopirati sve elemente iz starog u novi niz vodeći računa da li je potrebna duboka ili plitka kopija elemenata niza • Brisanje elementa niza treba da se isprogramira – pomeranje ostalih elemenata niza - zadnji i prezadnji element su isti • Dodavanje novog elementa niza takođe treba da se isprogramira – pomeranje ostalih elemenata niza pri čemu se gubi zadnji element niza
The ArrayList Collection Class • Kada se koristi ArrayList klasa: • Uklanjanje elementa iz kolekcije se vrši metodom Remove. Preostali elementi se automatski raspoređuju • Dodavanje elementa na sam kraj kolekcije se vrši metodom Add. Kolekcija se automatski produžava za jedan elemenat • Dodavanje elementa na proizvoljno mesto unutar kolekcije metodom Insert. Kolekcija se automatski produžava za jedan elemenat • Pristup elementima unutar kolekcije se vrši isto kao kod niza - Array
The ArrayList Collection Classprimer • using System; • using System.Collections; • ... • ArrayList numbers = new ArrayList(); • ... • // fill the ArrayList • foreach (int number in new int[12]{10, 9, 8, 7, 7, 6, 5, 10, 4, 3, 2, 1}) • { • numbers.Add(number); • } • ...
The ArrayList Collection Classprimer 2 • // insert an element in the penultimate position in the list, and move the last item up • // (the first parameter is the position; • // the second parameter is the value being inserted) • numbers.Insert(numbers.Count-1, 99); • // remove first element whose value is 7 (the 4th element, index 3) • numbers.Remove(7); • // remove the element that’s now the 7th element, index 6 (10) • numbers.RemoveAt(6);
The ArrayList Collection Classprimer 3 • // iterate remaining 10 elements using a for statement • for (int i = 0; i < numbers.Count; i++) • { • int number = (int)numbers[i]; // notice the cast, which unboxes the value • Console.WriteLine(number); • } • // iterate remaining 10 using a foreach statement • foreach (int number in numbers) // no cast needed • { • Console.WriteLine(number); • }
The Queue Collection Class • Queue klasa kolekcije implementira FIFO logiku • using System; • using System.Collections; • ... • Queue numbers = new Queue(); • ... • // fill the queue • foreach (int number in new int[4]{9, 3, 7, 2}) • { • numbers.Enqueue(number); • Console.WriteLine(number + “ has joined the queue”); • }
The Queue Collection Class • // iterate through the queue • foreach (int number in numbers) • { • Console.WriteLine(number); • } • ... • // empty the queue • while (numbers.Count > 0) • { • int number = (int)numbers.Dequeue(); // cast required to unbox the value • Console.WriteLine(number + “ has left the queue”); • }
The Stack Collection Class • Stack klasa kolekcije implementira LIFO logiku • using System; • using System.Collections; • ... • Stack numbers = new Stack(); • ... • // fill the stack • foreach (int number in new int[4]{9, 3, 7, 2}) • { • numbers.Push(number); • Console.WriteLine(number + “ has been pushed on the stack”); • }
The Stack Collection Class • // iterate through the stack • foreach (int number in numbers) • { • Console.WriteLine(number); • } • ... • // empty the stack • while (numbers.Count > 0) • { • int number = (int)numbers.Pop(); • Console.WriteLine(number + “ has been popped off the stack”); • }
The Hashtable Collection Class • Klasa kolekcije Hashtable omogućava indeksiranje elemenata kolekcije raznim drugim tipovima podataka osim tipom integer koji se koristi kod običnih nizova – Array • Klasa interno održava dva niza koji su povezani • Elementi jednog niza su ključevi i mogu biti integer, double, string, Time, dok su elementi drugog niza pridruženi i predstavljaju vrednosti. • Ključevi su jedinstveni i ne mogu se dodati duplikati • Klasa je veoma fleksibilna u pogledu tipova za ključeve i vrednosti – mogu biti vrednosni i referentni tipovi
The Hashtable Collection Classprimer • using System; • using System.Collections; • ... • Hashtable ages = new Hashtable(); • ... • // fill the Hashtable • ages[“John”] = 42; • ages[“Diana”] = 43; • ages[“James”] = 15; • ages[“Francesca”] = 13;
The Hashtable Collection Classprimer • // iterate using a foreach statement • // the iterator generates a DictionaryEntry object containing a key/value pair • foreach (DictionaryEntry element in ages) • { • string name = (string)element.Key; • int age = (int)element.Value; • Console.WriteLine(“Name: {0}, Age: {1}”, name, age); • }
The SortedList Collection Class • Klasa kolekcije SortedList je slična klasi Hashtable jer dozvoljava korišćenje ključeva kao index-a • SortedList omogućava sortiranje članova kolekcije na osnovu ključa • Za sortiranje je potrebno da tipovi podataka budu istog tipa da bi se mogli porediti • U petlji foreach se takođe koristi tip DictionaryEntry za pristup elementima kolekcije
The SortedList Collection Class primer • using System; • using System.Collections; • ... • SortedList ages = new SortedList(); • ... • // fill the SortedList • ages[“John”] = 42; • ages[“Diana”] = 43; • ages[“James”] = 15; • ages[“Francesca”] = 13;
The SortedList Collection Class primer • // iterate using a foreach statement • // the iterator generates a DictionaryEntry object containing a key/value pair • foreach (DictionaryEntry element in ages) • { • string name = (string)element.Key; • int age = (int)element.Value; • Console.WriteLine(“Name: {0}, Age: {1}”, name, age); • }
Inicijalizacija kolekcije • Inicijalizacija kolekcija koje koriste Add metod • ArrayList numbers = new ArrayList(){10, 9, 8, 7, 7}; • Interno se prethodna inicijalizacija realizuje preko niza poziva Add metoda – ne može za klase koje ne podržavaju Add – Stack i Queue • Inicijalizacija za klase sa key / value parovima • Hashtable ages = new Hashtable(){{“John”, 42}, {“Diana”, 43}, {“James”, 15}, {“Francesca”, • 13}};
Poređenje nizova i kolekcija • Kod nizova se deklarišu tipovi elemenata, dok se kod kolekcija ne deklarišu element jer se čuvaju kao objekti • Primerak niza ima fiksnu veličinu i ne može da se skraćuje i produžava • Nizovi mogu da imaju više dimenzija, dok su kolekcije linearne