1 / 53

RP3/predavanje06

RP3/predavanje06. Generici Kolekcije String, StringBuilder. Generički tipovi i metode. Višestruka iskoristivost koda može se postići nasljeđivanjem baznog tipa ili pomoću generika. Generici povećavaju tipsku sigurnost i smanjuju potrebu za kastanjem i pakiranjem.

brasen
Download Presentation

RP3/predavanje06

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. RP3/predavanje06 • Generici • Kolekcije • String, StringBuilder ---------- Računarski praktikum 3 ---------- Maja Starčević

  2. Generički tipovi i metode Višestruka iskoristivost koda može se postići nasljeđivanjem baznog tipa ili pomoću generika. Generici povećavaju tipsku sigurnost i smanjuju potrebu za kastanjem i pakiranjem. Generički tip sadrži generički parametar koji korisnik zamjenjuje s konkretnim tipom. Primjer: otvoreni tip List<T> --- > zatvoreni tip List<string> Računarski praktikum 3

  3. Generički tipovi Generički parametri mogu se nalaziti u deklaraciji klase, strukture, metoda, sučelja i delegata. U deklaraciji se može nalaziti i više takvih parametara: class Dictionary<TKeyValue, TValueType> { … } Dozvoljeno je preopterećivanje generičkih tipova i metoda, odnosno definiranje više tipova ili metoda s istim imenom, ali različitim brojem generičkih parametara. Računarski praktikum 3

  4. Generičke metode Generičke metode sadrže generičke parametre unutar potpisa. static void Zamijeni<T> (ref T a, ref T b) { T temp=a; a=b; b=temp; } ---------------------------------------------------------- int x=1, y=3; Zamijeni(ref x, ref y); // Kompilator implicitno dodjeljuje tip int Zamijeni<int>(ref x, ref y) ; // Može i eksplicitno Računarski praktikum 3

  5. Generički tipovi Na generičke parametre se mogu primijeniti ograničenjaako se zahtijeva veća specifikacija tipa. Računarski praktikum 3

  6. Generički tipovi Ukoliko se u listi nalazi više generičkih parametara s ograničenjem, navodimo where za svaki posebno: class Klasa< T , U > where T: struct where U: class, new( ) { …… } Primjer generičkog delegata: delegate T MyDelegate<T>( ) where T : new ( ) Računarski praktikum 3

  7. Generički tipovi class Klasa { int a; } class C<T> where T:struct { T t; } class D<T> where T :class { T t; } class Program { static void Main(string[] args) { C<int> c1; // C<Klasa> c2; // D<int> d1; D<Klasa> d2; } } Računarski praktikum 3

  8. Generički tipovi Zadatak: koje su od sljedećih generičkih metoda dobro definirane? public static bool Usporedi1<T>(T a, T b) { return a == b; } public static bool Usporedi2<T>(T a, T b) where T : struct { return a == b; } public static bool Usporedi3<T>(T a, T b) where T : class { return a == b; } public static bool Usporedi4<T>(T a, T b) { return a.Equals(b); } public static bool Usporedi5<T>(T a, T b) { return ReferenceEquals(a, b); } Računarski praktikum 3

  9. Generički tipovi Odgovor: Metode Usporedi1 i Usporedi 2 ne rade na svim vrijednosnim tipovima (nije osigurano da je operator == definiran za sve moguće strukture). public static bool Usporedi1<T>(T a, T b) { return a == b; } // greška public static bool Usporedi2<T>(T a, T b) where T : struct { return a == b; } // greška public static bool Usporedi3<T>(T a, T b) where T : class { return a == b; } public static bool Usporedi4<T>(T a, T b) { return a.Equals(b); } public static bool Usporedi5<T>(T a, T b) { return ReferenceEquals(a, b); } Računarski praktikum 3

  10. Generički tipovi Zadatak: popravite kod interface ICitljivo { void Citaj( );} class C<T> where T: ICitljivo { T t; void f( ) { t.Citaj( ); t.Pisi( ); } } class S { void Citaj( ) { } } class Program { static void Main(string[] args) { C<S> s; } } Računarski praktikum 3

  11. Generički tipovi interface ICitljivo { void Citaj( );} class C<T> where T: Icitljivo { T t; void f( ) { t.Citaj( ); t.Pisi( );} // T ne implementira sučelje koje pruža metodu Pisi( ) } class S : ICitljivo { public void Citaj( ) { } } class Program { static void Main(string[] args) { C<S> s; } } Računarski praktikum 3

  12. Generički tipovi class Program { static T Zbroj<T>(T a, T b) { return a + b; //error } static void Main(string[] args) { int a=1, b=2; int c = Zbroj(a, b); } } Napomena: u prethodnoj generičkoj metodi nije osigurano da će operator zbrajanja biti definiran za svaki mogući tip T. Također, nemoguće je pozvati se direktno na sučelje s obzirom da su operatori statičke funkcije, a takve se ne mogu nalaziti u sučeljima. Računarski praktikum 3

  13. Generički tipovi interface ICalculator<T> { T Suma(T a, T b); } struct IntCalculator : ICalculator<int> { public int Suma(int a, int b) { return a + b; } } class Program { public static T Zbroj<T, C>(T a, T b) where C : ICalculator<T>, new() { C c=new C(); return c.Suma(a, b); } static void Main(string[] args) { Console.WriteLine( Zbroj<int, IntCalculator>(1, 2) ); } } Moguće rješenje: Računarski praktikum 3

  14. Generički tipovi Napomena: od verzije C# 4.0 moguće je koristiti i ključnu riječ dynamic: class Program { static T Zbroj<T>(T x, T y) {dynamic dx = x, dy = y;return dx + dy;} static void Main(string[] args) { int a=1, b=2; int c = Zbroj(a, b); } } Računarski praktikum 3

  15. Generički tipovi U generičku metodu ubacit ćemo parametar tipa delegata kako bismo mogli pozivati konstruktor koji prima int: public class B { private int b; public B(){ b=0; } public B(int i){ b=i; } public override string ToString() { return b.ToString(); } } public class Program { public static T f<T>(int i, Func<int, T> metoda) where T : new() { return metoda(i); } static void Main(string[] args) { Func<int, B> del=(i=> new B(i)); B obj1=del(2); Console.WriteLine(obj1.ToString()); B obj2 = f<B>(2, del); Console.WriteLine(obj2.ToString()); } } Računarski praktikum 3

  16. Kolekcijske klase .NET Framework sadrži kolekcijske klase Array, List, Dictionary, Queue, Stack, SortedList, SortedDictionary … (u prostorima System.Collections, System.Collections.Generic, System.Collections.Specialized …) Sadrži i dva skupa standardnih sučelja za enumeriranje i uspoređivanje objekata u kolekciji - za tipski neosigurane kolekcije i noviju verziju, za generičke, tipski osigurane kolekcije. Računarski praktikum 3

  17. Kolekcijska sučelja Računarski praktikum 3

  18. Array Arrayje najjednostavnija kolekcija. To je kolekcija za koju C# ima ugrađenu podršku (ugrađeni indekseri za pristupanje n-tom članu). Primjer: int[ ] matrica=new int[4] u IL-kodu kreira instancu za System.Int32[ ] (izveden iz apstraktne klase System.Array). Računarski praktikum 3

  19. Array Metode i svojstva u System.Array: AsReadOnly( ), BinarySearch( ), Clear( ), Clone( ), ConstrainedCopy( ), ConvertAll( ), Copy( ), CopyTo( ), CreateInstance( ), Exists( ), Find( ), FindAll( ), FindIndex( ), FindLast( ), FindLastIndex( ), ForEach( ), GetEnumerator( ), GetLength( ), GetLongLength( ), GetLowerBound( ), GetUpperBound( ), GetValue( ), IndexOf( ), Initialize( ), IsFixedSize( ), IsReadOnly( ), IsSynchronized( ), LastIndexOf( ), Length( ), LongLength( ), Rank, Resize( ), Reverse( ), SetValue( ), Sort( ), SyncRoot( ), TrueForAll( ) Računarski praktikum 3

  20. Array class Program { public static void PrintArray(object[] array) { foreach (object obj in array) Console.WriteLine(obj); } static void Main(string[ ] args) { string[ ] recenica={ "Ovo", "je" ,"primjer"}; Array.Reverse(recenica); PrintArray(recenica); Array.Sort(recenica); PrintArray(recenica); } } Output: primjer je Ovo je Ovo primjer Računarski praktikum 3

  21. List Klasa Listpredstavlja matricu čija se veličina može po potrebi dinamički povećavati. Metode i svojstva u klasi List: Capacity, Count, Item( ), Add ( ), AddRange ( ), AsReadOnly ( ), BinarySearch( ), Clear( ), Contains( ), ConvertAll( ), CopyTo( ), Exists( ), Find( ), FindAll( ), FindIndex( ), FindLast( ), FindLastIndex( ), ForEach( ), GetEnumerator( ), GetRange( ), IndexOf ( ), Insert( ), InsertRange( ), LastIndexOf( ), Remove( ), RemoveAll( ), RemoveAt( ), RemoveRange( ), Reverse( ), Sort( ), ToArray( ), TrimExcess( ), TrimToSize( ) Računarski praktikum 3

  22. List using System; using System.Collections.Generic; using System.Text; public class Proizvod { string naziv; decimal cijena; public Proizvod(string naziv, decimal cijena) { this.naziv = naziv; this.cijena = cijena; } public string Naziv { get { return naziv; } set { naziv = value; } } public decimal Cijena { get { return cijena; } set { cijena = value; } } } class Program { static void Main(string[] args) { List<Proizvod> lista = new List<Proizvod>(); lista.Add(new Proizvod("Coca Cola“, 5.50M)); lista.Add(new Proizvod("Sprite", 5.25M)); Console.WriteLine(lista.Capacity); // 4 lista.Capacity = 2; Console.WriteLine(lista.Capacity); // 2 Console.WriteLine(lista[1].Cijena); //5,25 } } Računarski praktikum 3

  23. System.Collections System.Collections prostor sadrži negeneričke kolekcije poput ArrayList. Vrijednosni tipovi zahtjevaju pakiranje. using System.Collections; using System.Collections.Generic; …………. ArrayList alista = new ArrayList(); alista.Add("knjiga"); alista.Add(1); alista[1] = null; List<int> lista=new List<int>(); lista.Add(1); lista.Add(2); lista[1]=null; //greška Računarski praktikum 3

  24. Queue Queue(red) je kolekcija koja radi na principu first-in, first-out. Svojstva i metode kolekcije Queue: Računarski praktikum 3

  25. Queue Računarski praktikum 3

  26. Queue class Program { static void Main(string[] args) { Queue<Proizvod> red = new Queue<Proizvod>(); Proizvod p1 = new Proizvod(“Coca Cola", 5.45M); Console.WriteLine(red.Count); Console.WriteLine(red.Contains(p1)); red.Enqueue(p1); Console.WriteLine(red.Contains(p1)); Proizvod p2 = red.Peek(); Console.WriteLine(red.Count); Console.WriteLine(p1==p2); red.Dequeue(); Console.WriteLine(red.Contains(p1)); } } Output: 0 False True 1 True False Računarski praktikum 3

  27. Stack Stack(stog) je last-in, first-out kolekcija objekata. Metode i svojstva u kolekciji Stack: Računarski praktikum 3

  28. Stack Računarski praktikum 3

  29. Stack using System; using System.Collections.Generic; using System.Text; class Program { static void Main(string[] args) { Stack<int> stog = new Stack<int>(); for (int i = 0; i < 5; i++) stog.Push(i); stog.Pop(); int count = stog.Count; for(int i=0; i<count;i++) Console.WriteLine(stog.Pop()); Console.WriteLine( stog.Count); } } Output: 3 2 1 0 0 Računarski praktikum 3

  30. Dictionary Dictionary je kolekcija koja svakoj vrijednosti pridružuje ključ. Implementira IDictionary<K,V> sučelje (K-tip ključa, V-tip vrijednosti). .NET Framework može pridružiti ključ bilo kojeg tipa (string, integer, object, ...) vrijednosti bilo kojeg tipa. U pravilu je ključ jednostavnijeg tipa. Primjer 1: u rječniku stranih riječi svakoj riječi (ključ) pridružuje se definicija (vrijednost). Primjer 2: auto-oznake i gradovi. Računarski praktikum 3

  31. Dictionary using System; using System.Collections.Generic; using System.Text; class Program { static void Main(string[] args) { Dictionary<string, string> gradovi = new Dictionary<string, string>(); gradovi.Add("ZG", "Zagreb"); gradovi.Add("ST", "Split"); gradovi.Add("KA", "Karlovac"); gradovi.Add("RI", "Rijeka"); gradovi.Add("OS", "Osijek"); Console.WriteLine("Grad s autooznakom ST je {0}", gradovi["ST"]); } } C# implementacija svojstva Item( ) Računarski praktikum 3

  32. Dictionary Računarski praktikum 3

  33. Dictionary Računarski praktikum 3

  34. Dictionary Dictionary<string, string>.KeyCollection autoOznake = gradovi.Keys; foreach (string c in autoOznake) Console.WriteLine(c); Dictionary<string, string>.ValueCollection imenaGradova = gradovi.Values; foreach (string c in imenaGradova) Console.WriteLine(c); -------------------------------------------------------------------------------------------------------------- ZG ST KA RI OS Zagreb Split Karlovac Rijeka Osijek Računarski praktikum 3

  35. Sortirane kolekcije SortedDictionary<TKey,TValue> - kolekcija na principu ključ/vrijednost sortirana po ključu. SortedDictionary<int, string> sd = new SortedDictionary<int, string>(); sd.Add(2, "Zagreb"); sd.Add(1, "Split"); sd.Add(4, "Osijek"); sd.Add(3, "Rijeka"); foreach (KeyValuePair<int, string> kvp in sd) Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value); 1 – Split 2 – Zagreb 3 – Rijeka 4 - Osijek Da smo koristli Dictionary<int, string>, ispis bi odgovarao redoslijedu ubacivanja parova. Računarski praktikum 3

  36. IComparable Ako objekti u listi implementiraju sučelje IComparable<T>, na listu se može primijeniti Sort( ) metoda. Da bi objekt T implementirao sučelje IComparable<T> mora pružiti implementaciju CompareTo( ) metode. U sljedećem primjeru koristi se default CompareTo( ) metoda za tip string koja vraća vrijednosti -1 ( < ) , 1 ( > ) ili 0 (==). Računarski praktikum 3

  37. IComparable class Student:IComparable<Student> { public string ime; public string prezime; public Student (string ime, string prezime) { this.ime = ime; this.prezime=prezime; } public intCompareTo(Student s) { return this.prezime.CompareTo(s.prezime); } } class Program { static void Main(string[] args) { List<Student> lista= new List<Student>(); Student s1=new Student("Marko", "Maric"); lista.Add(s1); Student s2 = new Student("Ivan", "Ivic"); lista.Add(s2); Student s3 = new Student("Ana", "Anic"); lista.Add(s3); lista.Sort(); foreach (Student s in lista) Console.WriteLine(s.ime+” “+s.prezime); } } Računarski praktikum 3

  38. Enumerator Enumerator je klasa koja implementira sučelje IEnumerator ili generičko sučelje IEnumerator<T>. Mora implementirati metodu MoveNext (koja služi za iteriranje kroz niz) i svojstvo Current s get pristupnikom (za pristupanje trenutnom elementu niza). Enumerator je dakle read-only, forward-only kursor kroz niz vrijednosti. Računarski praktikum 3

  39. IEnumerable Klase koje implementiraju sučelje IEnumerable ili IEnumerable<T> pružaju mogućnost korištenja foreach naredbe za iteriranje kroz niz vrijednosti pripadnog objekta. Klasa koja implementira neko od navedenih sučelja mora implementirati metodu GetEnumerator koja stvara enumerator. Napomena: sučelja IEnumerable i IEnumerator su definirana u prostoru System.Collections dok se IEnumerable<T> i IEnumerator<T> nalaze u System.Collections.Generic. Računarski praktikum 3

  40. IEnumerable class Brojevi : IEnumerable { private List<int> lista; public IEnumeratorGetEnumerator() { foreach (int i in lista) yield return i; } public List<int> Lista { set { lista = value; } get { return lista; } } } class Program { static void Main(string[] args) { List<int> l = new List<int>(); l.AddRange(new int[] { 1, 2, 3, 4 }); Brojevi brojevi = new Brojevi(); brojevi.Lista=l; foreach (var i in brojevi) Console.Write(i); } } Računarski praktikum 3

  41. IEnumerable class Program { static IEnumerable<int> ProstiBrojevi(int n) { for(int i=2; i<=n; ++i) { bool prost=true; for (int j=2; j<=Math.Sqrt(i); ++j) if ((i%j)==0) prost=false; if (prost) yield return i; } } staticvoidMain(string[] args) { foreach (int i inProstiBrojevi(100)) Console.Write("{0} ", i); // isti ispis se postiže i s : IEnumerator<int>enumerator = ProstiBrojevi(100).GetEnumerator(); while (enumerator.MoveNext()) Console.Write("{0} ", enumerator.Current); } } Računarski praktikum 3

  42. IEnumerable Sada želimo da klasa umjesto sučelja IEnumerable implementira generičko sučelje IEnumerable<T>. Sučelje IEnumerable<T> proširuje sučelje IEnumerable te stoga takva klasa mora implementirati metode: IEnumerator GetEnumerator(); iz IEnumerator sučelja i IEnumerator<T> GetEnumerator() koja je dodana u IEnumerator<T> sučelje. Moramo implementirati svaku posebno jer imaju različite povratne tipove. Zbog istog potpisa jednu moramo implementirati eksplicitno. Računarski praktikum 3

  43. IEnumerable class C : IEnumerable<int> { int[] niz = new int[10]; public IEnumerator<int> GetEnumerator() // implicitna implementacija { foreach (int i in niz) yield return i; } IEnumerator IEnumerable.GetEnumerator() // eksplicitna implementacija { return GetEnumerator(); } } Računarski praktikum 3

  44. Zadatak Napišite klasu koja implementira IEnumerable<int> sučelje. Klasa sadrži listu brojeva. Treba implementirati i metodu Add( int ) za dodavanje broja u listu, metodu Remove( int ) kojom se izbacuje posljednji element liste koji ima zadanu vrijednost i Clear() kojom se brišu svi elementi liste. Klasa mora sadržavati i svojstvo Pomak. Ukoliko iteriramo kroz objekt klase foreach naredbom, moramo dobiti popis svih brojeva iz liste, ali ne uobičajenim redoslijedom nego sa zadanim pomakom, npr. za Pomak=3 i niz 1, 2, 3, 4, 5, 6, 7 dobivamo ispis 1, 4, 7, 3, 6, 2, 5. Ukoliko ne možemo na taj način proći kroz cijeli niz, mora se izbaciti iznimka s odgovarajućom porukom. U klasu stavite i funkciju Test( int ) koja testira foreach na nizu prvih n brojeva. Računarski praktikum 3

  45. String Puna deklaracija klase System.String (alias string u C#-u) glasi: public sealed class String : IComparable, IComparable<String>, ICloneable, IConvertible, IEnumerable, IEnumerable<char>, IEquatable<String> Računarski praktikum 3

  46. String class Program { staticvoid Usporedi(string a, string b) { Console.WriteLine("{0}, {1}, {2}", a == b, Object.ReferenceEquals(a, b), a.Equals(b)); } staticvoidMain(string[] args) { string s1 = "Rp3"; string s2 = "Rp3"; Usporedi(s1, s2); string s3= "Racunarski"; string s4 = s3; s3 += "praktikum 3"; // string je nepromjenjiv tip, konkatenacijom se zapravo stvara novi Usporedi(s3, s4); // string, referenca s3 se prebacuje na novi string } } Računarski praktikum 3

  47. String class Program { staticvoid Usporedi(string a, string b) { Console.WriteLine("{0}, {1}, {2}", a == b, Object.ReferenceEquals(a, b), a.Equals(b)); } staticvoidMain(string[] args) { string s1 = "Rp3"; string s2 = "Rp3"; Usporedi(s1, s2); string s3= "Racunarski"; string s4 = s3; s3 += "praktikum 3"; // string je nepromjenjiv tip, konkatenacijom se zapravo stvara novi Usporedi(s3, s4); // string, referenca s3 se prebacuje na novi string } } True, True, True False, False, False Računarski praktikum 3

  48. String Računarski praktikum 3

  49. String Računarski praktikum 3

  50. String Računarski praktikum 3

More Related