Arrays & Collections

Arrays & Collections

Περιγραφή

Σε αυτά τα tutorials θα δούμε πίνακες και διάφορα collections που μπορούμε να χρησιμοποιήσουμε στην C#, όπως

  • Arrays
  • ArrayList
  • Dictionary
  • List
  • Queue
  • Stack

Array – Πίνακας

 

 Τι είναι:

 Ο πίνακας είναι μια στατική δομή δεδομένων που μας επιτρέπει να αποθηκεύσουμε μέσα του δεδομένα του ίδιου τύπου. Οι πίνακες εμφανίζονται με δύο συνηθέστερες μορφές. Πίνακας μονοδιάστατος και δισδιάστατος.

Μονοδιάστατος πίνακας:

Η δήλωση ενός μονοδιάστατου πίνακα γίνετε με δύο τρόπους ως εξής:

int[] intArray = new int[20];

int[] intArray = new int[] {1,2,3,4,5};

 Στο πρώτο παράδειγμα δηλώνουμε έναν κενό πίνακα ακεραίων 20 θέσεων, ενώ με το δεύτερο παράδειγμα δηλώνουμε έναν πίνακα ακεραίων με τους αριθμούς 1,2,3,4,5 τα οποία εκχωρούνται στις θέσεις 0,1,2,3,4 αντίστοιχα μιας και η αρίθμηση των θέσεων του πίνακα ξεκινάει από το μηδέν. Επίσης στο δεύτερο παράδειγμα δεν έχουμε δηλώσει το μέγεθος γιατί το μέγεθος σε αυτή την περίπτωση υπολογίζεται κατευθείαν από τον αριθμό των παραμέτρων που έχουμε δώσει.

Δισδιάστατος πίνακας:

Για να δηλώσουμε έναν δισδιάστατο πίνακα κάνουμε τα εξής:

int[,] twodim = new int[3,4];

Έτσι δημιουργήσαμε έναν κενό πίνακα με 3 γραμμές και 4 στήλες.

Ή μπορούμε να τον αρχικοποιήσουμε με συγκεκριμένες τιμές.

int[,] twodim = new int[,]
{

  {1,2,3,4}  //Πρώτη γραμμή

  {5,6,7,8}  //Δεύτερη γραμμή

  {9,10,11,12} //Τρίτη γραμμή

};

 Σε γραφική απεικόνιση ο πίνακάς μας θα έχει την εξής μορφή.

1

2

3

4

5

6

7

8

9

10

11

12

Indexing

 Η αρίθμηση των θέσεων του πίνακα όπως αναφέραμε και πριν ξεκινάει από το μηδέν. Έτσι για να χρησιμοποιήσουμε ένα στοιχείο που βρίσκεται στην δεύτερη θέση του πίνακα αναφερόμαστε σε αυτό ως Πίνακας[1] κλπ.

int[,] twodim = new int[,]
{

  {1,2,3,4}  //Πρώτη γραμμή

  {5,6,7,8}  //Δεύτερη γραμμή

  {9,10,11,12} //Τρίτη γραμμή

};

Με τον ίδιο τρόπο χρησιμοποιούμε την αρίθμηση για να γεμίσουμε έναν πίνακα.
int[] array = new int[5];

array[0] = 1;

array[1] = 2;

array[2] = 3;

 

Ο πίνακας είναι μία στατική δομή δεδομένων και έχει σταθερό μέγεθος. Αν ο πίνακας που έχετε στην διάθεσή σας έχει 5 θέσεις και εσείς προσπαθήσετε να εισάγετε ή να διαβάσετε δεδομένα με την εντολή Πίνακας[5] το πρόγραμμα θα σας ειδοποιήσει όταν το "τρέξετε" ότι αντιμετώπισε exception καθώς η αρίθμηση ξεκινάει από το μηδέν οπότε η εντολή Πίνακας[5] δείχνει στην έκτη θέση του πίνακα η οποία δεν υπάρχει.

Επιπλέον δυνατότητες:

Ο πίνακας περιέχει τις ιδιότητες Length και LongLength οι οποίες μας δείχνουν το μέγεθος του πίνακα με 32 bit και 64 bit αντίστοιχα και την ιδιότητα Rank που μας λέει πόσες διαστάσεις έχει ο πίνακας.

int[] array = new int[]{1,2,3,4,5};

int number = array[1];

int anotherNumber = array[4];

Console.WriteLine(array.Length);

Console.WriteLine(array.Rank);

/*

5

1

*/

ArrayList

The ArrayList Collection

Τι είναι:

Η ArrayList είναι μια δυναμική δομή δεδομένων που σημαίνει ότι αντίθετα με τον πίνακα δεν έχει σταθερό μέγεθος. Yπάρχει στο .NET framework σαν έτοιμη κλάση και εκτός από το πλεονέκτημα του μεταβλητού μεγέθους προσφέρει και πολλές λειτουργίες όπως ταξινόμηση και αναζήτηση μεταξύ άλλων. Για να το χρησιμοποιήσετε πρέπει να εισάγετε το ακόλουθο namespace:  using System.Collections;

Δήλωση Arraylist:

Η ArrayList μπορεί να υλοποιηθεί με 3 τρόπους. Ο πρώτος τρόπος και ο πιο απλός είναι η δήλωση χωρίς παραμέτρους. Η ArrayList θα υλοποιηθεί με ένα αρχικό μέγεθος το οποίο θα διπλασιάζεται κάθε φορά που θα χρειαζόμαστε περισσότερο χώρο.

ArrayList myCollection = new ArrayList();

 Στην περίπτωση που ξέρουμε το μέγεθος που χρειαζόμαστε μπορουμε να το ορίσουμε περνώντας μία παράμετρο στην δήλωση.

 

ArrayList myCollection = new ArrayList(5);

Εδώ έχουμε ορίσει μία ArrayList 5 θέσεων. Στην περίπτωση που υποτιμήσαμε το μέγεθος που χρειαζόμαστε όταν χρησιμοποιηθεί η συλλογή μας το μέγεθός της θα διπλασιαστεί.

Ο τρίτος τρόπος μας δίνει την δυνατότητα να γεμίσουμε μία ArrayList με μία άλλη συλλογή η πίνακα.

string[] nameArray = new string[] { "Κώστας", "Μαρία", "Γιάννης" };

ArrayList nameCollection = new ArrayList(nameArray);

Indexing

 

Η αρίθμηση των θέσεων της ArrayList ξεκινάει από το μηδέν. Έτσι για να χρησιμοποιήσουμε/τροποποιήσουμε  ένα στοιχείο που βρίσκεται στην πρώτη θέση της ArrayList αναφερόμαστε σε αυτό ως ArrayList[0] κλπ.

string[] nameArray = new string[] { "Kwstas", "Maria", "Giannhs" };
ArrayList nameCollection = new ArrayList(nameArray);
Console.WriteLine(nameCollection[0]);
Console.WriteLine(nameCollection[1]);
Console.WriteLine(nameCollection[2]);

/* Output
Kwstas
 
Maria
 
Giannhs
*/

Μέθοδος Repeat

Με την μέθοδο Repeat μπορούμε να γεμίσουμε την συλλογή μας με την ίδια τιμή για όσες θέσεις θέλουμε. Αν θέλαμε για παράδειγμα να φτιάξουμε μία ArrayList με 5 θέσεις και όλες να έχουν την τιμή "Item" χρησιμοποιούμε την Repeat με τις εξής παραμέτρους.

ArrayList myCollection = ArrayList.Repeat("Item",5);

 Το αποτέλεσμα θα είναι αυτό:

Item

Item

Item

Item

Item

Μέθοδος AddRange

Μία επιπλέον δυνατότητα που έχουμε με την συλλογή ArrayList είναι το να εισάγουμε ένα πλήθος δεδομένων στο τέλος μίας ήδη υλοποιημένης ArrayList.

ArrayList Items= ArrayList.Repeat("Item",3);

ArrayList extraItems = ArrayList.Repeat("Extra",2);

Items.AddRange(extraItems);

 Το αποτέλεσμα θα είναι αυτό:

Item

Item

Item

Extra

Extra

Μέθοδος InsertRange

Στην περίπτωση που θέλουμε να βάλουμε τα Εxtra σε συγκεκριμένη θέση στον πίνακα και όχι στο τέλος υπάρχει η μέθοδος InsertRange η οποία με μία επιπλέον παράμετρο η οποία ορίζει την θέση από τη οποία θα αρχίσουν να μπαίνουν τα δεδομένα κάνει ακριβώς αυτό.

ArrayList Items= ArrayList.Repeat("Item",3);

ArrayList extraItems = ArrayList.Repeat("Extra",2);

Items.InsertRange(1,extraItems);

Το αποτέλεσμα είναι το ακόλουθο:

Item

Extra

Extra

Item

Item

Μέθοδος RemoveRange

Με την μέθοδο RemoveRange μπορούμε να αφαιρέσουμε ένα πλήθος δεδομένων από την Arraylist μας.

ArrayList items= ArrayList.Repeat("Item",5);

// Ξεκινώντας από την πρώτη θέση αφαίρεσε 3 στοιχεία

items.RemoveRange(0,3);

Το αποτέλεσμα θα είναι αυτό:

----

----

----

Item

Item

 

Μέθοδος IndexOf

Με την μέθοδο αυτή μπορούμε να ψάξουμε μέσα στην ArrayList μας για μία τιμή και αν βρεθεί η μέθοδος θα επιστρέψει τον αριθμό της θέσης της τιμής μέσα στην ArrayList αλλιώς θα επιστρέψει -1.

string[] array = new string[] { "One", "Two", "Find Me"};

ArrayList myCollection = new ArrayList(array);

int location1 = myCollection.IndexOf("Find Me", 0);

Console.WriteLine(location1);

/* Output
 
2

*/           

Μέθοδος Sort

Η συλλογή ArrayList περιέχει την μέθοδο Sort με την οποία ταξινομούμε τα στοιχεία της συλλογής.

string[] array = new string[] { "One", "Two", "Three" };

ArrayList myCollection = new ArrayList(array);

// Sort items

myCollection.Sort();

Console.WriteLine(myCollection[0]);

Console.WriteLine(myCollection[1]);

Console.WriteLine(myCollection[2]);

/* Output

One

Three

Two

*/

Μέθοδος TrimToSize και Ιδιότητα Capacity

Όπως αναφέρθηκε πριν η ArrayList αρχικοποιείτε με ένα συγκεκριμένο μέγεθος και στην συνέχεια αν χρειαστεί παραπάνω χώρος το μέγεθος διπλασιάζετε. Γιαυτό τον λόγο υλοποιώντας μία ArrayList υπάρχει περίπτωση να δεσμευτεί μαζί με τον χώρο που πραγματικά χρειάζεται και χώρος που θα μείνει άδειος. Αυτό το πρόβλημα λύνεται εύκολα με την μέθοδο TrimToSize() και κάνοντας χρήση της ιδιότητας Capacity μπορούμε να δούμε την διαφορά.

ArrayList myCollection = new ArrayList();

myCollection.Add("One");

myCollection.Add("Two");

myCollection.Add("Three");

myCollection.Add("Four");

myCollection.Add("Five");

int capacity = myCollection.Capacity;

Console.WriteLine("Initial capacity is {0} items", capacity);

myCollection.TrimToSize();

capacity = myCollection.Capacity;

Console.WriteLine("New capacity is {0} items", capacity);

/* Output

Initial capacity is 8 items

New capacity is 5 items

*/

List - Λίστα

 

Τι είναι:

 

Η λίστα είναι μια δυναμική δομή δεδομένων που μας επιτρέπει να αποθηκεύσουμε μέσα της δεδομένα του ίδιου τύπου. Για να χρησιμοποιήσετε την λίστα ( List<Τ> ) πρέπει να εισάγετε το namespace: using System.Collections.Generic

 

Δήλωση:

 

Ο πρώτος τρόπος δήλωσης και ο πιό απλός είναι ο εξής:

List<string> list = new List<string>();

Έτσι δημιουργούμε μία κενή λίστα. Άν ξέρουμε το μέγεθος που θέλουμε να έχει το ορίζουμε περνώντας μία παράμετρο κατά την δήλωση:

List<string> list = new List<string>(10);

Έτσι δημιουργούμε μία λίστα με 10 θέσεις.

 

Όταν χρησιμοποιούμε μία λίστα πρέπει να ορίσουμε αυστηρά το τύπο των δεδομένων που θα περιέχει. Αυτό γίνεται βάζοντας την έκφραση <Τ>. Όπου Τ είναι ο τύπος των στοιχείων πχ. <string>, <int>, <double> κλπ.

Εισαγωγή στοιχείων:

Σε μία λίστα μπορούμε να εισάγουμε στοιχεία με την μέθοδο Add(). Πχ:

List<string> list = new List<string>();

list.Add("Kwstas");

list.Add("Dimitris");

string name1 = list[0];

string name2 = list[1];

Console.WriteLine(name1);

Console.WriteLine(name2);

/*
 
Kwstas
 
Dimitris
 
*/

Indexing

Η αρίθμηση των θέσεων της λίστας ξεκινάει από το μηδέν. Έτσι για να χρησιμοποιήσουμε/τροποποιήσουμε  ένα στοιχείο που βρίσκεται στην πρώτη θέση της λίστας αναφερόμαστε σε αυτό ως Λίστα[1] κλπ.

List<string> list = new List<string>();

list.Add("Kwstas");

list.Add("Dimitris");

list[1] = "John";

string name1 = list[0];

string name2 = list[1];

Console.WriteLine(name1);

Console.WriteLine(name2);

/*
 
Kwstas

John

*/

 

Σε μία λίστα πρέπει να προσέξουμε να μην χρησιμοποιούμε στο indexing αριθμούς μεγαλύτερους από τον αριθμό των στοιχείων τα οποία έχουμε εισάγει με την μέθοδο Add().

 

Επιπλέον μέθοδοι:

 

Η λίστα υποστηρίζει τις μεθόδους AddRange(), InsertRange(), RemoveRange(), IndexOf()  και Sort() και χρησιμοποιούνται με τον τρόπο που εξηγούνται στην ενότητα ArrayList.

Queue - Ουρά

 

Τι είναι:

 

Η ουρά είναι μία δομή δεδομένων η οποία επιτρέπει την εισαγωγή στοιχείων για να εξαχθούν αργότερα με μία συγκεκριμένη σειρά. Η σειρά ονομάζεται First In – First Out (FIFO). Δηλαδή σε μία ουρά το πρώτο στοιχείο που θα μπεί είναι το πρώτο που θα βγεί. Για να χρησιμοποιήσετε την ουρά ( Queue ) πρέπει να εισάγετε το namespace: using System.Collections ενώ για την Queue<T> το : using System.Collections.Generic

Δήλωση:

 

Ο πρώτος τρόπος δήλωσης μίας ουράς και ο πιό απλός είναι ο εξής:

 

Queue q = new Queue();

Η ουρά μπορεί να περιέχει στοιχεία διαφορετικού τύπου. Αν θέλουμε να ορίσουμε μία ουρά που θα περιέχει μόνο έναν τύπο χρησιμοποιούμε την έκφραση <Τ>. Παράδειγμα:

Queue<string> q = new Queue<string>();

 

Έτσι δημιουργούμε μία κενή ουρά. Άν ξέρουμε το μέγεθος που θέλουμε να έχει το ορίζουμε περνώντας μία παράμετρο κατά την δήλωση:

 

Queue q = new Queue(10);

 

Έτσι δημιουργούμε μία ουρά με 10 θέσεις. Αν στην πορεία προσπαθήσουμε να εισάγουμε στην ουρά παραπάνω από 10 στοιχεία η ουρά αυτόματα θα διπλασιαστεί. Η ουρά διπλασιάζετε γιατί ο παράγοντας αύξησης είναι από προεπιλογή 2. Αν θέλουμε να τον αλλάξουμε το κάνουμε με τον παρακάτω τρόπο:

 

Queue q = new Queue(10, 1.5F);

Έτσι η ουρά αντί να γίνει 20 θέσεων θα γίνει 15 θέσεων.

 

Τέλος μπορούμε να δηλώσουμε μία ουρά και ταυτόχρονα να εισάγουμε μέσα στοιχεία που ήδη έχουμε σε μία άλλη δομή δεδομένων:

ArrayList al = new Arraylist();

al.Add(“string 1”);

al.Add(“string 2”);

Queue q = new Queue(al);

Εισαγωγή και Εξαγωγή στοιχείων:

 

Η ουρά έχει 2 ειδικές  μεθόδους που επιτρέπουν την εισαγωγή και εξαγωγή στοιχείων, σε αντίθεση με την πιο συνηθισμένη μέθοδο εισαγωγής Add(), την Enqueue() και την Dequeue() αντίστοιχα.

Queue q = new Queue();

//Eisagwgi

q.Enqueue("Kwstas");

q.Enqueue("Giannhs");

//Eksagwgi

string name1 = q.Dequeue().ToString(); // name1 = Kwstas

string name2 = q.Dequeue().ToString(); // name2 = Giannhs

Console.WriteLine(name1);

Console.WriteLine(name2);

/*
 
Κwstas
 
Giannhs
 
*/

 

Prosoxi Όταν χρησιμοποιούμε την μέθοδο Dequeue() δεν εξάγουμε αντίγραφο του στοιχείου αλλά το ίδιο το στοιχείο. Αυτό σημαίνει ότι μετά την εξαγωγή το στοιχείο δεν θα υπάρχει πλέον στην ουρά.

 

Επιπλέον μέθοδοι:

 

Μερικές φορές θέλουμε να δούμε ποιό είναι το επόμενο στοιχείο για εξαγωγή χωρίς όμως να το εξάγουμε. Για να το κάνουμε αυτό έχουμε την μέθοδο Peek(). Για να διαγράψουμε όλα τα στοιχεία της ουράς έχουμε την μέθοδο Clear().Η ουρά επίσης υποστηρίζει τις μεθόδους TrimToSize()  και Contains().

Queue q = new Queue();

q.Enqueue("Kwstas");

q.Enqueue("Giannhs");

int num = q.Count;

Console.WriteLine(num);

string name  = q.Peek().ToString();

Console.WriteLine(name);

int num2 = q.Count;

Console.WriteLine(num2);

q.Clear();

int num3 = q.Count;

Console.WriteLine(num3);

Console.WriteLine(q.Contains("Kwstas"));

Console.WriteLine(q.Contains("Maria"));

/* Output

2

Kwstas

2

0

False

False

*/


Stack - Στοίβα

 

Τι είναι:

 

Η Stack είναι μία δομή δεδομένων παρόμοια με την ουρά. Η διαφορά ανάμεσα στις 2 αυτές δομές είναι ότι η Stack εξάγει τα στοιχεία της με την σειρά Last In – First Out (LIFO) σε αντίθεση με την FIFO της ουράς. . Για να χρησιμοποιήσετε την στοίβα ( Stack ) πρέπει να εισάγετε το namespace: using System.Collections ενώ για την Stack<T> το : using System.Collections.Generic 

Δήλωση:

 

Ο πρώτος τρόπος και ο πιό απλός είναι ο εξής:

 

Stack st = new Stack();

 

Η στοίβα μπορεί να περιέχει στοιχεία διαφορετικού τύπου. Αν θέλουμε να ορίσουμε μία στοίβα που θα περιέχει μόνο έναν τύπο χρησιμοποιούμε την έκφραση <Τ>. Παράδειγμα:

Stack<string> q = new Stack<string>();

 

Έτσι δημιουργούμε μία κενή στοίβα. Άν ξέρουμε το μέγεθος που θέλουμε να έχει το ορίζουμε περνώντας μία παράμετρο κατά την δήλωση:

Stack st = new Stack(10);

Έτσι δημιουργούμε μία στοίβα με 10 θέσεις.

Τέλος μπορούμε να δηλώσουμε μία στοίβα και ταυτόχρονα να εισάγουμε μέσα στοιχεία που ήδη έχουμε σε μία άλλη δομή δεδομένων:

 

ArrayList al = new Arraylist();

al.Add(“string 1”);

al.Add(“string 2”);

Stack st = new Stack(al);

 

Εισαγωγή και Εξαγωγή στοιχείων:

 

Η στοίβα έχει 2 ειδικές  μεθόδους που επιτρέπουν την εισαγωγή και εξαγωγή στοιχείων την Push() και την Pop() αντίστοιχα.

 

Stack st = new Stack(al);

//Eisagwgi

st.Push(“Kwstas”);

st.Push (“Giannhs”); 

//Eksagwgi

string name1 = st.Pop(); // name1 = Kwstas

string name2 = st.Pop(); // name2 = Giannhs

 

Όταν χρησιμοποιούμε την μέθοδο Pop() δεν εξάγουμε αντίγραφο του στοιχείου αλλά το ίδιο το στοιχείο. Αυτό σημαίνει ότι μετά την εξαγωγή το στοιχείο δεν θα υπάρχει πλέον στην στοίβα.

 

Επιπλέον μέθοδοι:

 

Η στοίβα υποστηρίζει, όπως και η ουρά, τις μεθόδους Peek(),TrimToSize(), Clear()  και Contains().

Stack st = new Stack();

st.Push("Kwstas");

st.Push ("Giannhs");

Console.WriteLine(st.Count);

Console.WriteLine(st.Peek().ToString());

Console.WriteLine(st.Count);

Console.WriteLine(st.Contains("Kwstas"));

Console.WriteLine(st.Contains("Maria"));

st.Clear();

Console.WriteLine(st.Count);

/* Output

2

Giannhs

2

True

False

0

*/


Dictionary

Τι είναι:

Το dictionary είναι μία γενική δομή δεδομένων η οποία αποθηκεύει ζεύγη από τιμές key/value. Αυτό σημαίνει ότι ένα value είναι συνδεδεμένο με ένα μόνο key και χρησιμοποιόντας το key μπορούμε να εμφανίσουμε ή να τροποποιήσουμε το value του. Για να χρησιμοποιήσετε το Dictionary πρέπει να εισάγετε το namespace:  using System.Collections.Generic;

Δήλωση:

 

Ο πρώτος τρόπος για να δηλώσουμε ένα Dictionary είναι ο εξής:

Dictionary<int, string> dict = new Dictionary<int, string>();

Έτσι δημιουργούμε ένα κενό dictionary που δέχεται key τύπου int και value τύπου string. Άν ξέρουμε το μέγεθος που θέλουμε να έχει το ορίζουμε περνώντας μία παράμετρο κατά την δήλωση:

Dictionary<int, string> dict = new Dictionary<int, string>(20);

Έτσι δημιουργούμε ένα dictionary με 20 θέσεις.

Εισαγωγή  στοιχείων:

 

Η εισαγωγή στοιχείων γίνεται με την μέθοδο Add() με τον εξής τρόπο:

Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1, "Kwstas");// 1 = key, “Kwstas” = value

dict.Add(2, "Maria");

Για να εμφανίσουμε κάποιο στοιχείο του dictionary χρησιμοποιούμε indexing με τα keys που ορίσαμε. Το κάθε key αντιπροσωπεύει ένα μόνο value.

string x = dict[1];

string y = dict[2];

Console.WriteLine(x);

Console.WriteLine(y);

/* Output

Kwstas

Maria

*/

Επιπλέον μέθοδοι:

 

Το dictionary υποστηρίζει επίσης τις ιδιότητες Count, Keys, Values και τις μεθόδους ContainsKey και ContainsValue μεταξύ άλλων. Στο παρακάτω πρόγραμμα θα δούμε πως μπορούμε να τα χρησιμοποιήσουμε.

Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1, "Kwstas");// 1 = key, “Kwstas” = value

dict.Add(2, "Maria");

List<int> list1 = new List<int>(dict.Keys);

List<string> list2 = new List<string>(dict.Values);

Console.WriteLine(list1[0]);

Console.WriteLine(list2[1]);

Console.WriteLine(dict.Count);

bool a = dict.ContainsKey(1);

bool b = dict.ContainsValue("Giannhs");

Console.WriteLine(a);

Console.WriteLine(b);

/* Output

1

Maria

2

True

False

*/