Programmering för språkteknologer II, HT2014 Avancerad programmering för språkteknologer, HT2014 evelina.andersson@lingfil.uu.se Rum 9-2035 http://stp.ling.uu.se/~evelina/uv/uv14/pst2/ 1
Idag - Parametriserade typer - Abstrakt datatyp (ADT) - Listor och länkade strukturer - Komplexitet i länkade strukturer resp. arrayer - Undantag 2
Parametriserade typer (Generics) 3
Parametriserade typer (Generics) Exempel: ArrayList<String> list = new ArrayList<String>(); ArrayList<Integer> list = new ArrayList<Integer>(); Trevligt att kunna återanvända kod på det här sättet. Kan man skapa sådana här själv? 4
Parametriserade typer (Generics) Exempel: ArrayList<String> list = new ArrayList<String>(); ArrayList<Integer> list = new ArrayList<Integer>(); Trevligt att kunna återanvända kod på det här sättet. Kan man skapa sådana här själv? Ja!!! Det kallas för att parametrisera en klass. 5
Parametrisering på olika nivåer - Generiskt interface (gränssnitt): ett gränssnitt som kan hantera olika typer - Generisk klass: en klass som kan hantera olika typer - Generisk metod: en metod som kan hantera olika typer 6
Parametriserade typer (Generics) - En ArrayList beter sig likadant oavsett vad du lagrar i den - Implementationen är inte beroende av innehållet - Innehållets typ introduceras i en hållare, <...>, Dvs när man skapar en instans av klassen: Exempel: ArrayList<String> tokens = new ArrayList<String>(); ArrayList<Sentence> sentences = new ArrayList<Sentence>(); 7
Parametriserad metod - Exempel public append(arraylist<t> from, ArrayList<T> to) { for(t value: from) { to.add(value); Example: //call, assume that ArrayList<String> a and b exist append(a,b); 8
Parametriserad klass - Exempel public class MyClass<T> { T somevariable; ArrayList<T> somelistvarialble; public append(arraylist<t> from, ArrayList<T> to) { for(t value: from) { to.add(value); Example: public void foo() { // call, assume that ArrayList<String> a and b exist MyClass<String> c = new MyClass<String>(); c.append(a,b); 9
Parametrisering Komplikationer Om vi ger en abstrakt klass eller ett gränssnitt som parameter T? Exempel: ArrayList<MyInterface> list = new ArrayList<MyInterface>(); Problem: - Alla new T(...) blir ogiltiga 10
Parametrisering Komplikationer Om vi ger en abstrakt klass eller ett gränssnitt som parameter T? Problem: - Alla new T(...) blir ogiltiga Lösningar: - Använd endast implementerade klasser som parametrar - Skapa aldrig instanser av parametertyper T x = new T(); 11
Parametrisering Komplikationer Man kan aldrig göra följande: - Skapa objekt av typen T T x = new T(); - Skapa arrayer av objekt av typen T T[] x = new T[size]; 12
Parametrisering Komplikationer Man kan aldrig göra följande: - Skapa objekt av typen T olösligt T x = new T(); - Skapa arrayer av objekt av typen T T[] x = new T[size]; Lösning: T[] array = new (T[]) Object[size]; 13
Parametrisering Komplikationer Lösning: T[] array = new (T[]) Object[size]; Problem: - Man får följande varning: MyClass.java uses unchecked or unsafe operations 14
Parametrisering Komplikationer Problem: - Man får följande varning: MyClass.java uses unchecked or unsafe operations Lösning: Man kan skriva följande: @SuppressWarning( unchecked ) public T[] makearray(int size) { return (T[]) new Object[size]; 15
Parametrisering Komplikationer @SuppressWarning( unchecked ) public T[] makearray(int size) { return (T[]) new Object[size]; @SuppressWarning( unchecked ) - Är ett exempel på en Annotation - Undertrycker alla varningar för metoden makearray(). Kompileringen går problemfritt. 16
Parametrisering Komplikationer Problem: Det går inte att använda compareto()eftersom den inte finns för alla typer. Lösning: Det går att koppla en paremtriserad typ till ett interface eller en klass. Metoden compareto()är definierad i gränsnittet Comparable. Exempel: public class MyClass<T> extends Comparable<T> {... Nu kan den parametriserade klassen endast hantera klasser som implementerar Comparable. compareto() kan användas. 17
Parametrisering Komplikationer Problem: Det går inte att använda compareto()eftersom den inte finns för alla typer. Lösning: Det går att koppla en paremtriserad typ till ett interface eller en klass. Metoden compareto()är definierad i gränsnittet Comparable. Exempel: public class MyClass<T> extends Comparable<T> {... Nu kan den parametriserade klassen endast hantera klasser som implementerar Comparable. compareto() kan användas. Detta kallas för att koppla en parametrierad typ till ett interface/klass 18
Abstrakt datatyp 19
Abstrakt datatyp(adt) - En ADT beskriver vad man kan göra med en typ men inte hur den här implementerad: ADT MyClass() append() tostring() Implementering 20
Abstrakt datatyp(adt) - En ADT beskriver vad man kan göra med en typ men inte hur den här implementerad: ADT MyClass() append() tostring() Implementering - I java motsvaras en ADT oftast av ett gränssnitt som beskriver vilka metoder som ska finnas med i en ADT. 21
Abstrakt datatyp(adt) - Exempel - En lista är en abstrakt datatyp är finit och ordnad, dvs alla objekt I listan har en viss plats motsvarar begreppet sekvens i matematiken Man kan definiera vilka med metoder som ska finnas med för en lista 22
Lista Gränsnitt - Vad ska man kunna göra med en lista? Svar: I Java motsvaras en lista av gränssnittet List som bland annat innehåller följande metoder: boolean isempty() boolean addelement(e element) boolean add(int index, E element) E get(int index) E remove(int index)... 23
Lista Implementation - Det är inte specifierad hur en lista ska implementeras, men två vanliga metoder är: med hjälp av en array som en länkad struktur 24
Lista Implementeras med hjälp av en array - I klassen ArrayList representeras listan av en array T[] som består av 10 celler: T 25
Lista Implementeras med hjälp av en array - I klassen ArrayList representeras listan av en array T[] som består av 10 celler: T - När arrayen blir full, så skapas det en större array och innehåller från den gamla arrayen kopieras över till den nya: Detta tar tid 26
Lista Implementeras med hjälp av en array - I klassen ArrayList representeras listan av en array T[] som består av 10 celler: T - När arrayen blir full, så skapas det en större array och innehåller från den gamla arrayen kopieras över till den nya: Detta tar tid - I en array har vi random access vilket innebär att vi kan komma åt element var som helst o arrayen på konstant tid 27
Lista Implementeras med en länkad struktur - en länkad struktur består av noder 28
Implementeras med en länkad struktur - en länkad struktur består av noder data data data - varje nod består av data 29
Implementeras med en länkad struktur - en länkad struktur består av noder data data data - varje nod består av data och en pekare till nästa nod 30
Implementeras med en länkad struktur - en länkad struktur består av noder data data data - varje nod består av data och en pekare till nästa nod - Då den sista noden inte länkas till någon nod, har den en nullpekare: 31
Implementeras med en länkad struktur - en länkad struktur består av noder data data data - varje nod består av data och en pekare till nästa nod - Då den sista noden Inte länkas till någon noden, så har den ingen pekare - För att kunna arbeta med den länkade strukturen, räcker det med att känna till den första noden. 32
Implementeras med en länkad struktur data data data Den här strukturen kallas för enkellänkad lista 33
Enkellänkade listor klassen Node Noderna implementeras med hjälp av klassen Node: private class Node<T> { T data; Node next; Node(T v, Node n) { data=v; next=n; data next data next data next 34
Enkellänkade listor klassen MyLinkedList Den enkellänkade listan representeras av klassen MyLinkedList<T>: public class MyLinkedList<T> { private class Node<T> { T data; Node next; Node(T v, Node n) { data=v; next=n; data next data next data next private Node<T> head = null; 35
Enkellänkade listor Operationer 36
Enkellänkade listor Operationer - Sätt in ett nytt värde - Hämta värdet i en nod i en viss position - Ta bort ett värde 37
Enkellänkade listor Operationer addfirst(t data) 38
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; 39
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head 40
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head addfirst(2) 41
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head addfirst(2) newhead data next 2 42
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head head addfirst(2) data next 2 43
Enkellänkade listor Operationer addfirst(t data) Den enkellänkade listan ser nu ut så här: head data next 2 44
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head addfirst(3) data next 2 45
Enkellänkade listor Operationer addfirst(t data) public void addfirst(t v) { Node newhead = new Node(v,head); head=newhead; head addfirst(3) data next 3 data next 2 data next 2 46
Enkellänkade listor Operationer addfirst(t data) public void add(t v) { Node newhead = new Node(v,head); head=newhead; head head addfirst(3) data next 3 data next 2 data next 2 47
Enkellänkade listor Operationer addfirst(t data) Den enkellänkade listan ser nu ut så här: head data next 3 data next 2 48
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) { break; currentnode = currentnode.next; currentindex++; return currentnode.data; 49
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 data next 2 50
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 51
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 52
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 53
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 54
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 55
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 56
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 0 currentnode data next 2 57
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 58
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 59
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 60
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 61
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 62
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 63
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 index 1 currentindex 1 currentnode data next 2 64
Enkellänkade listor Operationer get(int index) public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; head data next 3 Värdet 2 returneras! currentnode data next 2 65
Enkellänkade listor Operationer remove(int index) public T remove(int index) { if(index = 0 && head!= null) { head=head.next; else { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; else { currentnode = currentnode.next; currentindex++; if(currentnode.next!= null) { currentnode.next = currentnode.next.next; 66
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data data currentnode 67
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data data currentnode 68
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data data currentnode 69
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data data currentnode 70
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data currentnode 71
Enkellänkade listor Operationer remove(int index) public T remove(int index) {... if(currentnode.next!= null) { currentnode.next = currentnode.next.next; data data currentnode Javas garbage collection tar hand om den nod som togs bort. 72
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v, int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode 73
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v, int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode newnode T 74
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v, int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode newnode T 75
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v,int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode newnode T 76
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v,int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode newnode T 77
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v,int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data currentnode newnode T 78
Enkellänkade listor Operationer add(t v,int index) //Lägg till en ny nod sist i listan public T add(t v,int index) {... if(currentnode.next == null) { Node newnode = new Node(v,null); currentnode.next = newnode; data data T currentnode 79
Enkellänkade listor Operationer tostring() public String tostring() { Node currentnode = head; StringBuilder res = new StringBuilder(); while (currentnode!= null) { res.append(current.data + " "); currentnode = currentnode.next; return res.tostring(); 80
Olika typer av länkade listor Enkellänkad lista: Varje nod pekar på nästa nod Klassen känner till den första noden i listan head data data data 81
Olika typer av länkade listor Enkellänkad lista: Varje nod pekar på nästa nod Klassen känner till den första noden i listan head data data data Dubbellänkad lista: Varje nod pekar på både föregående och nästa nod Klassen känner till den första och den sista noden i listan Klassen LinkedList i java är dubbellänkad head 1 2 3 end prev data next 82
Olika typer av länkade listor Enkellänkad lista: Varje nod pekar på nästa nod Klassen känner till den första noden i listan I vissa implementationer känner man även till den sista noden också head data data data Dubbellänkad lista: Varje nod pekar på både föregående och nästa nod Klassen känner till den första och den sista noden i listan Klassen LinkedList i java är dubbellänkad head 1 2 3 end prev data next 83
Enkellänkade listor Tidskomplexitet Hämta värde: - Först i listan: O(1) - På plats n : O(n) Insättning/borttagning: - Först i listan: O(1) - På plats n : O(n) - Själva insättningen/borttagningen: O(1) - Sist i listan: O(1) om det finns en pekare till det sista noden annars O(n) 84
Andra länkade strukturer Binära träd 85
Binärt sökträd - Exempel key 1 2 3 4 5 6 7 8 9 86
Binärt sökträd - Exempel key 1 2 3 4 5 6 7 8 9 key == 5? Färdig key < 5? Sök i vänster barn key > 5? Sök i höger barn 87
Binärt sökträd - Exempel key 5 1 2 3 4 6 7 8 9 key == 5? Färdig key < 5? Sök i vänster barn key > 5? Sök i höger barn 88
Binärt sökträd - Exempel key 5 1 2 3 4 6 7 8 9 key == 3? Färdig key < 3? Sök i vänster barn key > 3? Sök i höger barn 89
Binärt sökträd - Exempel key 5 3 6 7 8 9 1 2 4 key == 3? Färdig key < 3? Sök i vänster barn key > 3? Sök i höger barn 90
Binärt sökträd - Exempel key 5 3 6 7 8 9 2 4 1 key == 2? Färdig key < 2? Sök i vänster barn key > 2? Sök i höger barn 91
Binärt sökträd - Exempel key 5 3 6 7 8 9 2 4 1 key == 8? Färdig key < 8? Sök i vänster barn key > 8? Sök i höger barn92
Binärt sökträd - Exempel key 5 3 8 2 4 6 7 9 1 key == 8? Färdig key < 8? Sök i vänster barn key > 8? Sök i höger barn93
Binärt sökträd - Exempel key 5 3 8 2 4 7 9 1 6 key == 7? Färdig key < 7? Sök i vänster barn key > 7? Sök i höger barn94
Binärt sökträd - Exempel 5 3 8 2 4 7 9 1 6 95
Binärt sökträd Datastruktur - Binärt sökträd består av noder med följande innehåll: - nyckel - data - pekare till vänster barn - pekare till höger barn Left child key data Right child 96
Binärt sökträd Datastruktur 5 3 8 2 4 7 9 1 6 97
Binärt sökträd klassen MyBinaryTree public class BinaryTree<T> { private class Node<T> { T data; Node left; Node right; Node(T v, Node l, Node r) { data=v; Left=l; right=r; private Node<T> root; 98
Träd - Fakta 5 3 8 2 4 7 9 1 6 ROT Noden högst upp i trädet Inre noder Noder som har en förälder och minst ett barn LÖV (TERMINAL) Noderna längst ner i trädet 99
Träd - Fakta 5 3 8 2 4 7 9 1 6 ROT Noden högst upp i trädet Inre noder Noder som har en förälder och minst ett barn LÖV (TERMINAL) Noderna längst ner i trädet 100
Träd - Fakta 5 3 8 2 4 7 9 1 6 ROT Noden högst upp i trädet Inre noder Noder som har en förälder och minst ett barn LÖV (TERMINAL) Noderna längst ner i trädet 101
Obalanserat träd - Exempel 1 2 3 4 5 6 7 8 9 Antal noder: 9 Höjd: 9 Söktid: O(n) 102
Balanserat träd - Exempel 5 3 8 2 4 7 9 1 6 Antal noder: 9 Höjd: 4 Söktid: O(log n) 103
Hur kan vi garantera att ett träd är balanserat? Idé: Varje gång vi lägg in en nod i trädet, kontrollerar vi att det är i balans. Metoder: - AVL-träd - Röd-Svarta träd - Heap träd Påverkar inte tidskomplexiteten: - Man söker på nervägen och balanserar på tillbakavägen. 104
Balanserade träd komplexitet Insättning: O(log n) borttagning: O(log n) Sökning: O(log n) Traversering: O(n) - Man går igenom trädet och besöker varje nod exakt en gång. Detta görs med hjälp av rekursion. 105
Sortering i listor - De sorteringsalgoritmer vi gick igenom förra gången fungerar på arrayer eftersom de bygger på random access 106
Sortering i listor - De sorteringsalgoritmer vi gick igenom förra gången fungerar på arrayer eftersom de bygger på random access - Algoritmerna är väldigt ineffektiva på länkade strukturer 107
Sortering i listor - De sorteringsalgoritmer vi gick igenom förra gången fungerar på arrayer eftersom de bygger på random access - Algoritmerna är väldigt ineffektiva på länkade strukturer - Vissa går att modifiera för länkade strukturer Exempel: Instickssortering och merge sort 108
Sortering i listor - De sorteringsalgoritmer vi gick igenom förra gången fungerar på arrayer eftersom de bygger på random access - Algoritmerna är väldigt ineffektiva på länkade strukturer - Vissa går att modifiera för länkade strukturer Exempel: Instickssortering och merge sort Alternativ: Lägg till datan i sorterad ordning, Enkelt i länkade listor Opraktiskt att göra i en array Kan vara bättre att använda ett binärt sökträd 109
Komplexitet för olika listimplementationer och sökträd Array Länkad lista Binärt sökträd Iteration O(n) O(n) O(n) Söka efter ett värde O(n) O(n) O(log n) Hämta värde på index i O(1) O(n) -------- Sätta in värde först O(n) O(1) -------- Sätta in värde på index i O(n) O(n) -------- Sätta in värdet sist O(1) O(1) eller O(n) -------- Sätta in ett värde sorterat O(n) O(n) O(log n) Ta bort det första värdet O(n) O(1) -------- Ta bort värdet på index i O(n) O(n) -------- Ta bort ett givet värde O(n) O(n) O(log n) 110
Komplexitet för for-loop for(int i = 0; i < collection.size(); i++) { // Do something with collection[i] 111
Komplexitet för for-loop for(int i = 0; i < collection.size(); i++) { // Do something with collection[i] Array Länkad lista Loop med indexering O(n ) O(n 2) 112
Komplexitet för for-each-loop for(t data: collection.size()) { // Do something with data Array Länkad lista For-each loop O(n) O(n ) For-each loopen loopar igenom listan med hjälp av en Iterator mer om detta nästa gång 113
ADT- Vilken datastruktur ska man välja? - Beror på uppgiften! Tips: Tänk igenom vilka operationer du behöver utföra ofta Om man ska söka ofta: Använd binärt sökträd eller en hashtabell Om man ska loopa igenom samlingen ofta: - Om antalet element är konstant använd array - Om antalet element varierar mycket eller är okänt: använd en länkad lista - Om man ofta behöver sätta in värden i samlingen: använd en hashtabell 114
Undantag(Exception) 115
Undantag (Exception) - Om något konstigt händer i en klass kan man göra följande: - Kasta ett undantag i klassen tala om att något konstigt hänt - Låta en annan klass ta hand om felet felet hanteras utan att programmet kraschar 116
Undantag (Exception) Hur kastar man undantag? Exempel: public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException(); UnsupportedOperationException Undantag som talar om att denna operation inte är tillåten. Används till exempel när klassen implementerar ett gränssnitt och gränssnittet innehåller metoder som inte ska ingå i klassen. Exempel: Man kan inte ta bort element mitt i stacken men vi behöver implementera remove() för kunna använda Iterator. 117
Undantag (Exception) Hur kastar man undantag? Exempel: public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException(); throws Används för att tala om att den här metoden kastar ett undantag throw Används för att kasta undantaget 118
Undantag (Exception) Hur kastar man undantag? UnsupportedOperationException - en undantagsklass som ärver från klassen Exception. new UnsupportedOperationException(); - skapar en instans av klassen 119
Undantag (Exception) Klassdiagram Throwable Error Exception RuntimeException UnsupportedOperation Exception... 120
Undantag (Exception) Klassdiagram Throwable Error Error Fel som inte beror på programmet själv utan på något som sker utanför. Går inte att hantera. Exempel: Programmet behöver mer minne men det har tagit slut. 121
Undantag (Exception) Klassdiagram Throwable Error Exception RuntimeException RuntimeException Beror på misstag i programmeringen 122
Undantag (Exception) RuntimeException Beror på misstag i programmeringen Exempel 1: ArrayIndexOutOfBoundsException - Händer när man försöker göra använda ett index utanför en array. String[] array = new String[4]; array[-1] = "Outside"; array[2] = "inside"; array[5] = "Outside"; //error // ok // error 123
Undantag (Exception) RuntimeException Beror på misstag i programmeringen Exempel 2a: NullPointerException - Händer när man försöker använda null. int number = 1 + null; // error 124
Undantag (Exception) RuntimeException Beror på misstag i programmeringen Exempel 2b: NullPointerException - Händer när man försöker använda null. Node current = null; current = current.next; // ok! // error! current: next saknas om current har värdet null 125
Undantag (Exception) RuntimeException Beror på misstag i programmeringen Åtgärd Rätta till programmet. Hur hitta felet i programmet? Tips: Gör utskrifter med System.out.println(..); på olika ställen i programmet. 126
Undantag (Exception) Klassdiagram Throwable Error Exception UnsupportedOperation Exception... Övriga exception - Fel som är svåra att förutse - Man kan hantera undantaget. 127
Undantag (Exception) Övriga exception - Fel som är svåra att förutse - Man kan hantera undantaget. Passiv hantering Metoden kastar vidare undantaget som remove() kastar. Exempel: public void removeeverything(iterator<integer> it) throws UnsupportedOperationException { while(it.hasnext()) { Integer i = it.next(); it.remove(); 128
Undantag (Exception) Övriga exception - Fel som är svåra att förutse - Man kan hantera undantaget. Aktiv hantering Metoden fångar undantaget och utför en åtgärd. try { // satser man försöker exekvera catch (Exception e) { // Här hamnar man om ett undantag kastades // när satserna exekverades 129
Undantag (Exception) Övriga exception - Fel som är svåra att förutse - Man kan hantera undantaget. Aktiv hantering Metoden fångar undantaget och utför en åtgärd. Exempel: public void removeeverything(iterator<integer> it){ while(it.hasnext()) { Integer i = it.next(); try { it.remove(); catch(unsupportedoperationexception e) { System.err.println (e + "was handled in" + "in removeeverything."); 130
Undantag (Exception) Övriga exception - Fel som är svåra att förutse - Man kan hantera undantaget. Aktiv hantering Metoden fångar undantaget och utför en åtgärd. Vad göra i catch-blocket? - Skriva ett felmeddelande: System.err.println(e + "was handled in" + "in removeeverything."); System.err.println(""); Används för att skriva ut något på error-strömmen istället för out-strömmen. 131
Undantag (Exception) Vad göra i catch-blocket? - Skriva ett felmeddelande: System.err.println(e + "was handled in" + "in removeeverything."); System.err.println(""); Används för att skriva ut något på error-strömmen istället för out-strömmen. - Kasta ett nytt undantag - Tilldela andra värden på variabler osv. 132
Undantag (Exception) Vilka undantag måste man hantera? Alla undantag utom Error och RuntimeException måste hanteras. Om man vill kasta ett exception som inte finns i någon undantagsklass? Skapa en nya undantagsklass. 133
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedList<T>. 1. Använd klassen Exception som superklass, dvs skapa en klass som ärver från den. public class MyLinkedListException extends Exception {... 134
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedList<T>. 1. Använd klassen Exception som superklass, dvs skapa en klass som ärver från den. public class MyLinkedListException extends Exception {... 2. Skapa de konstruktorer du vill använda. // default konstruktor public MyLinkedListkException() { super(); 135
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedList<T>. 2. Skapa de konstruktorer du vill använda. // default konstruktor public MyLinkedListException() { super(); // konstruktor om man vill skapa ett undantag med // ett meddelande public MyLinkedListException(String message) { super(message); 136
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedList<T>. 2. Skapa de konstruktorer du vill använda. // konstruktor om man vill skapa ett undantag med // ett meddelande och ett (nytt) undantag. // Man kan skapa en kedja av undantag. public MyLinkedListException(String message, Throwable cause) { super(message, cause); 137
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedLList<T>. 2. Skapa de konstruktorer du vill använda. // konstruktor om man vill skapa ett undantag med // ett (nytt) undantag. // Man kan skapa en kedja av undantag. public MyLinkedListException(Throwable cause) { super(cause); 138
Undantag (Exception) Skapa en egen undantagsklass till klassen MyLinkedList<T>. public class MyLinkedListException extends Exception { public MyLinkedListException() { super(); public MyLinkedListException(String message) { super(message); public MyLinkedListException(String message, Throwable cause) { super(message, cause); public MyLinkedListException(Throwable cause) { super(cause); 139
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index)med ett index som ligger utanför listans storlek, till exempel index<0, eller om listan är tom? 140
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index) på en tom enkellänkad lista? head index 1 public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; 141
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index) på en tom enkellänkad lista? head index 1 currentnode currentindex 0 public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; 142
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index) på en tom enkellänkad lista? head index 1 currentnode currentindex 0 public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; 143
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index) på en tom enkellänkad lista? head index 1 currentnode currentindex 0 public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; 144
Undantag (Exception) Använda MyLinkedListException i klassen MyLinkedList<T>. Vad händer om vi anropar get(index) på en tom enkellänkad lista? head index 1 currentnode currentindex 0 public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; currentnode = currentnode.next; currentindex++; return currentnode.data; Programmet kraschar eftersom currentnode har värdet null 145
Undantag (Exception) Istället för att krascha programmet kan vi kasta MyLinkedListException: public T get(int index) throws MyLinkedListException { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; if(currentnode.next!= null) { currentnode = currentnode.next; currentindex++; else { throw new MyLinkedListException(); if(currentnode!= null) { return currentnode.data; else { throw new MyLinkedListException(); 146
Undantag (Exception) Istället för att krascha programmet kan vi kasta MyLinkedListException: public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; if(currentnode.next!= null) { currentnode = currentnode.next; currentindex++; else { throw new MyLinkedListException(); if(currentnode!= null) { return currentnode.data; else { throw new MyLinkedListException(); 147
Undantag (Exception) Istället för att krascha programmet kan vi kasta MyLinkedListException: public T get(int index) { Node currentnode = head; int currentindex = 0; while (currentnode!= null) { if (currentindex == index) break; if(currentnode.next!= null) { currentnode = currentnode.next; currentindex++; else { throw new MyLinkedListException(); if(currentnode!= null) { return currentnode.data; else { throw new MyLinkedListException(); 148
Undantag (Exception) - Kasta med eller utan meddelande: throw new MyLinkedListException(); throw new MyLinkedListException("Information"); - Metoder man kan använda för att få information om undantaget: String getmessage() returnerar meddelandet eller null om det inte finns String tostring() returnerar en sträng som innehåller namnet på undantaget och eventuellt meddelande catch (MyLinkedListException e) { System.out.println("Something went wrong " + e); 149
Lab 2, del 2 - Sökning Kandidat: - Ni får en given klass med kod för linjär sökning binär sökning, rekursiv binär sökning, iterativ - Koden är skriven för arrayer med heltal, int[] Uppgift -- Gör om klassen så att den blir generisk -- Gör om koden så att den fungerar för generisk ArrayList<T> Master: Implementera Binärt sökträd 150
Kommande veckor Sökning och sortering Deadline lab 2: 29/9 Tema datastrukturer, paket, iteratorer mm (v. 39-41) Föreläsning om iteratorer, stackar och köer mm Två labtillfällen 151
Jobba själv - Labbar Lab2 - Gör progammeringsövningar Från boken - Läs om veckans område Sökning Sortering Komplexitet - Läs inför nästa vecka Parametriserade typer Länkade strukturer Stackar och köer Undantag 152