TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Kort om javadoc Abstrakta datatyper Ordböcker/Mappar Listor Stackar Köer Mängder Iteratorer 1
Abstrakta Datatyper (ADT) Abstraktion (subst.) En tankeprocess i vilken man bortser från vissa egenskaper hos en företeelse eller ett föremål och i stället uppmärksammar en eller några få egenskaper Källa: Nationalencyklopedin (förkortad form) Abstrakt datatyp En datatyp där man bortser från implementationsspecifika egenskaper och istället uppmärksammar en eller några få egenskaper. ADT implementeras med lämpliga datastrukturer och algoritmer Datastruktur - Logisk organisation av datorminne för lagring av data Algoritm En uppsättning instruktioner för att lösa en uppgif 2
Abstrakta Datatyper (ADT) T.ex, datatyp för att representera datum. Datatyp för att representera länkad lista. Datatyp för att representera filer. I mer konkreta termer, ADT:er är nya datatyper som bygger på de grundläggande, men: Inkapsling är viktigt, för att: a) Vi vill inte bekymra oss om detaljer / låg nivå (d.v.s. implementation) när vi jobbar med vårt program. b) Vi vet att implementation kan behövas bytas senare, men vi vill inte att det skall påverkar vårt program. 3
Abstrakta Datatyper (ADT)(2) Scenario: Du skriver ett program som hanterar samtliga studenter godkända på en kurs. Programmet ska spara för varje student om de klarat av kursen eller ej. Behov: En abstrakt datatyp (ADT) som kan hjälpa till med ovannämda Vad för ADT kan vi välja? Vilka typer av data skall lagras? Person Lisa Pelle Eva Klarad Kurs? ja nej nej 4
ADT Ordbok ADT: Ordbok (nyckel-värde par) (eng. Map, Dictionary) Domän: En linjärt ordnad mängd nycklar K (studenter) och värden V (ja eller nej) Operationer (ett urval): lookup(nyckel) => värde add(nyckel, värde) (heter get i Javas Map) (heter put i Javas Map) remove(nyckel, värde) Fler detaljer än dessa inte synliga för användaren 5
ADT Ordbok Implementation Implementationsexempel för vår ordbok Personnummer som strängar i en array. Godkänt eller ej som booleans i en annan array. Algoritmer för operationerna... MyDictionaryImpl - pnrs : Strings[] - passed : boolean[] +lookup(pnr : String) : boolean +add(pnr : String, pass : boolean) +remove(... Vi skulle nu kunna gå vidare och lösa vårt scenario. MyDictionaryImpl students = new MyDictionaryImpl(); students.add( 880725-9505, true); 6
ADT Ordbok (i Java) I java finns flera implementationer att välja bland (?). HashMap (bygger på arrayer) TreeMap (bygger på trädstrukturer) Använder en gemensam abstrakt klass. Map +get(key) : Value +put(key, value) HashMap - keys : Key[] - values : Value[] +get(key) : Value +put(key, value) - root : Node TreeMap +get(key) : Value +put(key, value) Vi kan använda ADT m.h.a. den abstrakta klassen. Då kan vi enkelt byta implementation senare. Map students = new HashMap(); // nu behöver vi endast ändra här boolean haspassed = students.get( 880725-9505 ); 7
Abstrakta Datatyper Sammanfattning: ADT:er säger vad som kan göras För att bestämma hur det ska göras Map Välj datastruktur +get(key) : Value +put(key, value) Konstruera algoritmer för ADT:ns operationer Samma ADT kan implementeras HashMap med - root - keys : Key[] - values : Value[] Olika datastrukturer +get(key) : Value Olika algoritmer +put(key, value) : Node TreeMap +get(key) : Value +put(key, value) 8 Välj den ADT som är mest lämplig för ditt problem. Välj den implementation som är mest effektiv i just ditt fall.
Abstrakta Datatyper (ADT)(2) Flyttal: Ett oväntat exempel på en abstrakt datatyp(adt) Vi behöver ej känna till exakt hur flyttalet fungerar internt i datorn Detaljer kan variera mellan programspråk Formatet är rätt komplext, ex. Java definierar en float med formeln s * c * 2q, där s är -1/1, c 23 bit och q 8 bit Allt vi behöver veta är Domänen, d.v.s. reella tal Operationerna, +, -, *, /, osv. Vi förväntar oss samma uppsättning operationer på flyttal överallt Endast flyttals-kontraktet måste följas Kod som använder flyttal blir därmed frikopplad från specifik implementation 9
ADT Lista En av de mest använda abstrakta datatyperna Godtyckligt antal element (av samma typ) kan lagras Numrerad Går att hämta element m.h.a. index Storleken: Antal element lagrade i listan Kan implementeras både med array eller länkade noder 10
ADT Lista(2) En delmängd av standardgränssnittet för ADT Lista: void add(x) Lägg till x i slutet av listan void addfirst(x) Lägg till x i början av listan void remove(x), remove(i) Ta bort x /elementet på plats i boolean contains(x) True om det finns ett likadant element int indexof(x) Returnerar index för x x get(i) Returnerar elementet på index i 11
ArrayList En implementation av ADT:n Lista Representerar datat i någon form av fält + Kan hämta ut element med index snabbt - Långsam vid insättning i början av listan - Långsam vid borttagning. Behöver allokera om fältet (och kopiera över) då maxstorlek uppnås. I Java: ArrayList<Animal> arrlist = new ArrayList<Animal>(); 12
Enkellänkad Lista En implementation av ADT:n Lista Representerar datat i noder med referens till eferföljande nod Har ofa även ett huvud med lite extra information H D D D / + Kan lägga till element i (början av) listan snabbt - Långsam då den hämtar ut element av ett visst index... I Java: LinkedList<Animal> slist = new LinkedList<Animal>(); 13
Lite igen om referenser Variabler av icke primitiva datatyper är alltid referenser i java. Måste instansieras innan de används. Två variabler kan referera till samma minnesutrymme. Human a = new Human( Kalle ); Human b = a; b.setname( Lisa ); a: Lisa b: Objekt behöver ej destrueras! (avallokeras) 14
Länkad struktur En klass kan innehålla en variabel av samma typ som klassen själv! class Node { String data; Node next; } 15
Dubbellänkad Lista En implementation av ADT:n Lista Representerar datat i noder med referens till eferföljande och föregående nod Har ofa även ett huvud med lite extra information, ibland dessutom en svans. Så kallade sentinel-noder H / D D D / - Kräver större minnesutrymme + går snabbare att t.ex. sortera I Java: LinkedList är egentligen en dubbellänkad lista... 16
Kö (en. Queue) Du är en kock på en restaurang. Servitör / servitris kommer in med beställningar som läggs i kö. När du skall göra en maträtt tar du alltid den beställning som ligger först i kön (den har väntat längst). mmmm. 18
Kö (en. Queue) Först in först ut (FIFO) Metoder front() / peek() Returnerar främsta elementet dequeue() Tar bort och returnerar det främsta elementet void enqueue(e) Lägger till ett element i slutet av kön boolean isempty() Returnerar sant om kön är tom int size() Returnerar antalet element i kön Exempel på användning: Inmatningsbuffert I Java (använd LinkedList som implementation): Queue<Animal> que = new LinkedList<Animal>(); 19
Stack Du är en diskare på en restaurang. Servitör / servitris bär in disk och lägger längst upp på din hög (en stack). Du tar alltid översta tallriken när du skall diska nästa. 20
Stack Sist in först ut (LIFO) Metoder top() / peek() Returnerar stackens toppelement utan att ta bort det pop() Tar bort och returnerar stackens toppelement void push(element) Lägger till ett element på toppen av stacken boolean isempty() Returnerar sant om stacken är tom int size() Returnerar antal element i stacken Obs! Datastrukturen kanske är implementerad precis som en annan ADT, men uppsättningen operationer skiljer. I Java: Stack<Animal> stack = new Stack<Animal>(); 21
Hitta felet! public class StackTest { public static void main(string[] args) { Stack stack = new Stack(); stack.push(34); int i = stack.pop(); stack.push(i); stack.pop(); stack.peek(); stack.pop(); } } Försäkra dig om att stacken inte är tom innan du försöker komma åt topelementet. 22 att (Ett Exception kommer kastas här!)
Mängd (eng Set) Metoder add() - Lägger till ett element i mängden. remove(element) Tar bort och returnerar ett element union(set) slår ihop två mängder (heter addall i java) intersection(set) tar snittet av två mängder (heter retainall i java) Tillåter inte dubletter! I Java (finns både HashSet och TreeSet) Set<Animal> mangd = new HashSet<Animal>(); 23
Sammanfattning ADT:er De ADT:er vi tittat på har olika kvalitéer... Lista Linjär struktur Element kan kommas åt/läggas till via index. Stack Linjär struktur Element kan endast kommas åt/läggas till vid toppen. Kö Linjär struktur Element kan endast läggas till i början. Element kan endast kommas åt i slutet. Ordbok / Map Associativ struktur Datat ordnat I en tabell med nyckel-värdepar. Mängd (eng. Set) Ej linjär struktur. Element kan läggas till, och tas bort. Inga dubbletter tillåts. I java är dessa Interface. Tillhörande implementationsklasser finns i paketet java.util. 24
Testa dig själv Vilken ADT är lämpligast? Kö Vi vill representera en meddelandekanal för ett chatt-program. Vi vill representera en meny på restaurang. Lista Vi vill representera dagens för varje veckodag. Map (Veckodag Maträtt) Vi vill representera vilka bord på restaurangen som för nuvarande är lediga. Vi vill representera specialkost veg/gluten/laktos för varje rätt på menyn. Mängd Map (Bord Boolean) Map (Maträtt (Mängd av specialkost) ) 25
Iteratorer Harry har skrivit ett program som använder en av dessa ADT:er. (samlingar). Han vill nu besöka alla värden i ADT:n (loopa över). Problem: Olika ADT:er har ev. olika sätt som man tar fram elementen. Vad händer om han byter senare? Lösning: Vi gör något gemensamt för alla. 26 Iteratorer!
Collection I Java ärver sådana ADT:er från Javas Collection. Alla sådana ADT:er kan ge en Iterator. Ett objekt som kan traversera alla elementen. Collection +iterator() ArrayList LinkedList HashSet TreeMap Collection är abstrakt och tvingar subklasser att implementera metoden +iterator() som skall skapa ett skräddarsytt objekt för att traversera just den samlingen. 27
Iteratorer(2) Ett sätt att iterera över alla element i en datastruktur utan att behöva känna till implementationen! Skapas ofast av datastrukturen genom att anropa metoden iterator(). Har metoderna: hasnext() kolla om det finns något mer element att besöka. next() plockar fram nästa element. remove() plockar bort de element som sist gavs av next(). List<String> mylist = SingleLinkedList<String>(); Iterator<String> i = mylist.iterator(); while (i.hasnext()) { System.out.print(i.next()); } 28
Iteratorer(3) Eller det inbygda sättet: List<String> mylist = SingleLinkedList<String>(); for (String data : mylist) { System.out.print(data); } 29