Wiederholung Universität Paderborn Prof. Dr. Heike Wehrheim Exceptions: Ausnahmen, die während der Programmausführung auftreten Behandlung: try { …… } catch (ExceptionTyp1 e1) { … } catch (ExceptionTyp2 e2) { … } Selber auslösen: throw new SomeException(“Katastrophe“) GP1- WS 08/09 552 Grundprinzipien Universität Paderborn Prof. Dr. Heike Wehrheim Ausnahmebehandlung: Das Auslösen einer Ausnahme bricht eine Operation, die umgebenden Anweisungen, die verursachenden Methodenaufrufe ab bis eine passende Ausnahmebehandlung gefunden wird. Beim Auslösen einer Ausnahme wird ein Ausnahmeobjekt erzeugt. Seine Klassenzugehörigkeit charakterisiert die Ausnahme (z. B. NoSuchElementException). Es kann Information (z.B. einen Fehlertext als String) zur Ausnahmebehandlung transportieren. Die catch-Klauseln einer try-Anweisung sind Ausnahmebehandlungen für jeweils die angegebene Klasse von Ausnahme-Objekten. Wird ein try-Block durch eine Ausnahme der Klasse E abgebrochen und hat er eine Ausnahmebehandlung für E (oder eine Oberklasse von E, kommt noch), so wird diese ausgeführt und damit die try-Anweisung beendet. Hat er keine solche Ausnahmebehandlung, so wird auch die try-Anweisung abgebrochen. GP1- WS 08/09 553 Reihenfolge der „catches“ Universität Paderborn Prof. Dr. Heike Wehrheim try { …… } catch (ExceptionTyp1 e1) { … } catch (ExceptionTyp2 e2) { … } … catch (ExceptionTypn en) { … } Exception aus try-Block wird der Reihe nach mit den Exceptiontypen verglichen, der erste passende wird genommen Deshalb: erst die spezialisierteren, dann die allgemeineren Typen GP1- WS 08/09 554 Weiteres Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel mit mehreren Exceptions und einer „eigenen“ Exception: public static void main(String [] args) { Scanner s = new Scanner(System.in); int a=0, b=0, c=0; try { System.out.print("Geben Sie zwei int-Zahlen ein: "); a = s.nextInt(); b = s.nextInt(); if (a==0 && b==0) throw new Exception ("Nur mit Nullen rechne ich nicht!"); c = a/b; } catch(InputMismatchException i) { System.out.println("Formatfehler: "+i); } catch(NoSuchElementException n) { System.out.println("\nEingabe leer: "+n); } catch(ArithmeticException ae) { Catch mit System.out.println("Rechenfehler: "+ae); } Exception ex catch(Exception ex) { als letztes! System.out.println("Sonstiger Fehler: "+ex); } } GP1- WS 08/09 555 Frage Universität Paderborn Prof. Dr. Heike Wehrheim Gegeben eine Datei zahlen.txt mit mehr als 210 Zahlen. Scanner sc = new Scanner( new File("zahlen.txt")); try { for (int i = 0; i<=10; i++) { int n = sc.nextInt(); System.out.println(n); } } catch (NoSuchElementException e) { } Wieviele Zahlen werden gelesen? (a)10 (b) 11 (c) keine (d) 210 GP1- WS 08/09 556 Frage Universität Paderborn Prof. Dr. Heike Wehrheim static String liesPasswort () throws NoSuchElementException { int fehler = 0; String passwort; Scanner sc = new Scanner(System.in); while (true) { try { System.out.println("Geben Sie das Passwort ein: "); passwort = sc.nextLine(); break; Break verlässt die Schleife } sofort catch (NoSuchElementException e) { System.out.println("Eingabefehler, versuchen Sie es erneut"); fehler = fehler + 1; if (fehler >= 3) throw new NoSuchElementException(); } } return passwort; } Wie ist der Ablauf im Normalfall? Was passiert, wenn sc.nextLine() jedesmal eine NoSuchElementException wirft? GP1- WS 08/09 557 Universität Paderborn Prof. Dr. Heike Wehrheim Kapitel 3: Dynamische Datenstrukturen Listen und Bäume GP1- WS 08/09 558 Wiederholung Rekursion Universität Paderborn Prof. Dr. Heike Wehrheim Rekursive Funktionen rufen sich selber auf Eine Aufgabenstellung auf die Lösung der Aufgabe selber zurückführen Es gibt eine (oder mehrere) „einfachste“ Aufgaben/Fälle Abbruchbedingung der Rekursion: einfachster Fall GP1- WS 08/09 559 Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel Schreiben Sie eine rekursive Methode static int summe(int m, int n), welche die Summe der Zahlen von m bis n berechnet, m und n positiv. Beispiel: summe(5,5) summe(6,3) summe(2,4) GP1- WS 08/09 -> 5 -> 0 -> 9 560 Lösung Universität Paderborn Prof. Dr. Heike Wehrheim static int summe(int m, int n) { if (m > n) return 0; if (m == n) return m; else return m + summe(m+1,n); } Wie oft wird summe bei Aufruf summe(3,5) aufgerufen, und mit welchen Werten für m und n? GP1- WS 08/09 561 Motivation Universität Paderborn Prof. Dr. Heike Wehrheim Bisher gesehen: Rekursive Methoden Definition einer Methode durch sich selbst Jetzt: Rekursive Datenstrukturen Definition der Datenstruktur durch sich selbst Zweck (z.B.): wollen eine am Programmanfang nicht vorhersehbare Menge von Daten speichern; diese müssen nicht notwendigerweise zusammenhängend hintereinander gespeichert werden die einzelnen Datenelemente selber wissen, wo das nächste Element steht GP1- WS 08/09 562 Universität Paderborn Prof. Dr. Heike Wehrheim Zugbeispiel 4 12 15 3 die Datenstruktur Zug: Hat Lokomotive, daran hängt ein Wagen An Wagen hängt entweder weiterer Wagen oder gar nichts Rekursion Abbruchbedingung GP1- WS 08/09 563 Universität Paderborn Prof. Dr. Heike Wehrheim Zugbeispiel 4 12 15 3 Aufgaben: Anzahl der Wagen zählen Wagen mit Nummer 12 da? Letzten Wagen abhängen GP1- WS 08/09 564 Lineare Listen Universität Paderborn Prof. Dr. Heike Wehrheim Lineare Listen repräsentieren Folgen gleichartiger Elemente als dynamisch veränderliche Datenstruktur mit linearem Zugriff. Listen werden aus Paaren aufgebaut: (Elementwert, Referenz auf den Rest der Liste) G P1- WS 08/09 565 Operationen auf Listen Universität Paderborn Prof. Dr. Heike Wehrheim Oft: „Zeiger verdrehen“ Einfügung der 7 nach der 2: 1-2-3-4-5 → 1-2-7-3-4–5 Löschung der 4: → 1-2-7-3–5 GP1- WS 08/09 566 Implementierung Universität Paderborn Prof. Dr. Heike Wehrheim Implementierung in Java: nicht notwendig gleichartige Elemente, Elemente sind Objektreferenzen der Klasse Object jedes Objekt ist (auch) vom Typ Object Klasse Node ("Knoten") für Paare (Element, Rest der Liste): class Node { Object data; Node link; Node (Object d, Node n) { data = d; link = n; } } Ein Objekt dazu: GP1- WS 08/09 567 Erläuterung Universität Paderborn Prof. Dr. Heike Wehrheim Die vordefinierte Klasse Object umfasst Objektreferenzen beliebiger Klassen Element muß ein Objekt sein, also „Wrapper“ für Werte von Grundtypen Deklaration einer Listenvariable, initialisiert mit einer 1-elementigen Liste: Node list = new Node (new Integer (5), null); null: vordefinierter Name für die einzige Referenz, die kein Objekt identifiziert GP1- WS 08/09 568 Elementare Operationen Universität Paderborn Prof. Dr. Heike Wehrheim Aufbauen einer Liste in umgekehrter Reihenfolge: Node list = null; for (int i = n; i > 0; i--) list = new Node (new Integer (i), list); Die komplette Liste durchlaufen – etwa zum Drucken (Anfangszeiger ist list): l = list; while (l != null) { System.out.print(l.data+" "); l = l.link; } alternativ: for (l = list; l != null; l = l.link) System.out.print(l.data+" "); GP1- WS 08/09 569 Weitere Operationen Universität Paderborn Prof. Dr. Heike Wehrheim Einen Elementwert zahl in der Liste list suchen: Integer zahlObj = new Integer (zahl); Node l = list; boolean gefunden = false; while ((l != null) & !gefunden) { if (l.data.equals (zahlObj)) gefunden = true; else l = l.link; } ListenTest.java Ein Element d nach dem Objekt l einfügen (l sei != null): l.link = new Node (d, l.link); GP1- WS 08/09 570 Frage Universität Paderborn Prof. Dr. Heike Wehrheim list = null; for (int i = 1; i < 5; i++) list = new Node (new Integer (i), list); Node l = list; l = l.link; l.link = new Node(new Integer(99), l.link); l = l.link; l.link = l.link.link; Wie sieht die Liste am Ende aus? Welche Elemente referenzieren l und list? GP1- WS 08/09 571 Eigene Aufgabe Universität Paderborn Prof. Dr. Heike Wehrheim Schreiben Sie einen Programmteil, der die Anzahl der Elemente in einer Liste zählt. Node list = …; gegeben. Achtung: den Anfang der Liste wollen Sie behalten; list darf nicht geändert werden GP1- WS 08/09 572 Lösung Universität Paderborn Prof. Dr. Heike Wehrheim Node list = …; Node l = list; int zähler = 0; while (l != null) { zähler++; l = l.link; } GP1- WS 08/09 573