Erstes Java Programm public class Hello { 3. Java Einführung } Moderner Euklid Algorithmus in Java, Ein- und Ausgabe in Java Klasse: Ein Programm public static void main (String[] args) { System.out.println("Hello World."); } Methode: benannte Folge von Anweisungen. Anweisung: Kommando, auszuführen ist. welches Aufruf einer Methode (Prozedur) einer anderen Klasse. Aufruf: java Hello 69 Java Klassen 70 Der euklidische Algorithmus in Java public class Euclidean { Java-Programm besteht aus mindestens einer Klasse. Ein Java-Programm hat eine Klasse mit main-Funktion (Methode). Diese spielt die Rolle des Programmrumpfes bei Pascal public class Test{ // potentiell weiterer Code und Daten } public static void main(String[] args) { ... } } 71 public static void main(String[] args){ Variablen müssen vor Gebrauch deklariert werden. int a = 24; Keine separate Deklarationssequenz nötig. int b = 20; Anweisungsblöcke sind durch geschweifte while (b != 0) { Klammern gekennzeichnet. if (a>b) Bedingungen stehen bei if und while ima = a − b; mer in runden Klammern. else b = b − a; } System.out.println("ggt(24,20)= " + a); } 72 Nachteil dieser Variante Schneller so! while (b != 0) { if (a>b) a = a − b; else b = b − a; } ab ab ab ab ab ab ab ab ab a b a mod b b 73 74 Moderne (und effizientere) Variante Mit einer Funktion (Methode) public class Euclidean { public class Euclidean { static int ggt(int a, int b){ while (b != 0) { int h = a % b; a = b; b = h; } return a; } } public static void main(String[] args){ int a = 24; int b = 20; while (b != 0) { int h = a % b; // modulo! a = b; b = h; } System.out.println("ggt(24,20)=" + a); } } 75 public static void main(String[] args){ System.out.println("ggt(24,20)= " + ggt(24,20)); } 76 Ein- und Ausgabe Mit Eingabe Ausgabe via System.out mit import java.util.Scanner; System.out.print(...); System.out.println(...); public class Euclidean { static int ggt(int a, int b){ ... } // wie oben Eingabe via System.in mit einem Scanner: Scanner input = new Scanner(System.in); String s = input.next(); int i = input.nextInt(); benötigt einen Import: } import java.util.Scanner; public static void main(String[] args){ Scanner input = new Scanner(System.in); int a = input.nextInt(); int b = input.nextInt(); System.out.println("ggt(" + a + "," + b + ")= " + ggt(a,b)); } 78 77 Zeichenketten (Strings) Zuweisung eines Stringliterals: String hello = "Hallo Leute"; Stringlänge: 4. Java - Sprachkonstrukte I int len = hello.length(); Elementzugriff3 Namen und Bezeichner, Variablen, Zuweisungen, Konstanten, Datentypen, Operationen, Auswerten von Ausdrücken, Konversionen, Kontrollfluss, Klassen, statische Methoden char c = hello.charAt(5); Verkettung String helloLong = hello + ". Alles wird gut."; 3 Nur lesend. Strings sind unveränderlich 79 80 Namen und Bezeichner Namen - was ist erlaubt Ein Programm (also Klasse) braucht einen Namen _myName public class SudokuSolver { ... me@home TheCure Konvention für Klassennamen: CamelCase benützen → Wörter sind zusammengeschrieben mit jeweils einem Grossbuchstaben __AN$WE4_1S_42__ Erlaubte Namen für “Entitäten” im Programm: Namen beginnen mit einem Buchstaben oder _ oder $ Danach Folge von Buchstaben, Zahlen oder _ oder $ strictfp ?! 49ers side-swipe $bling$ Ph.D’s 81 Schlüsselwörter Variablen und Konstanten Folgende Wörter werden von der Sprache bereits benützt und können deshalb nicht als Namen benützt werden: abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float 82 for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super Behälter für einen Wert. Haben einen Datentyp und einen Namen Der Datentyp bestimmt, welche Art von Werten in der Variable erlaubt sind switch synchronized this throw throws transient try void volatile while int x int y float f char c 23 42 0.0f ’a’ Deklaration in Java: int x = 23, y = 42; float f; char c = ’a’; Initialisierung 83 84 Konstanten Standardtypen Schlüsselwort final Der Wert der Variable kann genau einmal gesetzt werden. Beispiel final int maxSize = 100; Tip: Benützen Sie final immer, es sei denn der Wert muss tatsächlich veränderlich sein. Datentyp Definition Wertebereich Initialwert byte short int long 8-bit Ganzzahl 16-bit Ganzzahl 32-bit Ganzzahl 64-bit Ganzzahl −128, . . . , 127 −320 768, . . . , 320 767 −231 , . . . , 231 − 1 −263 , . . . , 263 − 1 0 0 0 0L float double 32-bit Fliesskommazahl 64-bit Fliesskommazahl ±1.4E −45 , . . . , ±3.4E +38 ±4.9E −324 , . . . , ±1.7E +308 0.0f 0.0d boolean Wahrheitswert true, false false char String Unicode-16 Zeichen Zeichenkette ’\u0000’,. . . ,’a’,’b’,. . . ,’\uFFFF’ ’\u0000’ ∞ null 85 Typen und Speicherbelegung 86 Wertzuweisungen Zur Erinnerung: Speicherzellen enthalten 1 Byte = 8 bit Kopiert einen Wert in die Variable x boolean In Pseudocode: x ← Wert In Java: x = Wert byte x Wert (Kopie) Wert short, char “=” ist der Zuweisungsoperator und nicht ein Vergleich! int, float int y = 42 ist also Deklaration + Wertzuweisung in einem. long, double 87 88 Wertzuweisungen Arithmetische Binäre Operatoren Beispiele Infix Notation: x op y mit folgenden Operatoren int a = 3; double b; op: b = 3.141; int c = a = 0; Eine verschachtelte Zuweisung: Der Ausdruck a = 0 speichert den Wert 0 in Variable a. und gibt den Wert danach zurück +−∗/ % Modulo Division x / y : Ganzzahldivision falls x und y Ganzzahlen sind. Beispiele Ganzzahldivision und Modulo String name = "Inf"; 5 / 3 ergibt 1 5 % 3 ergibt 2 −5 / 3 ergibt −1 −5 % 3 ergibt −2 90 89 Arithmetische Zuweisung x = x + y m x += y Arithmetische Unäre Operatoren Prefix Notation: + x oder − x Unäre Operatoren binden stärker als binäre. Beispiele: x −= 3; // x = x − 3 name += "x" // name = name + "x" num ∗= 2; // num = num ∗ 2 Beispiele Angenommen x ist 3 2 ∗ −x ergibt −6 −x − +1 ergibt −4 Analog für −, ∗, /, % 91 92 Inkrement/Dekrement Operatoren Inkrement/Dekrement Operatoren Inkrement Operatoren ++x und x++ haben den gleichen Effekt: x ← x + 1. Beispiele Angenommen x ist initial 2 y = ++x ∗ 3 ergibt: x ist 3 und y ist 9 y = x++ ∗ 3 ergibt: x ist 3 und y ist 6 Aber unterschiedliche Rückgabewerte: Präfixoperator ++x gibt neuen Wert zurück: a = ++x; ⇐⇒ x = x + 1; a = x; Postfixoperator x++ gibt den alten Wert zurück: a = x++; ⇐⇒ temp = x; x = x + 1; a= temp; Analog für x−− und −−x. 94 93 Ausdrücke (Expressions) Ausdrücke (Expressions) repräsentieren Berechnungen sind entweder primär oder zusammengesetzt . . . . . . aus anderen Ausdrücken, mit Hilfe von Operatoren sind statisch typisiert Beispiele primär: “−4.1d” oder “x” oder "Hi" zusammengesetzt: “x + y” oder “f ∗ 2.1f” Der Typ von “12 ∗ 2.1f” ist float Analogie: Baukasten 95 96 Celsius zu Fahrenheit Celsius zu Fahrenheit - Analyse import java.util.Scanner; 9 * celsius / 5 + 32 public class Main { } public static void main(String[] args) { System.out.print("Celsius: "); Scanner input = new Scanner(System.in); int celsius = input.nextInt(); float fahrenheit = 9 * celsius / 5 + 32; System.out.println("Fahrenheit: " + fahrenheit); } Arithmetischer Ausdruck, enthält drei Literale, eine Variable, drei Operatorsymbole Wie ist der Ausdruck geklammert? Beispiel: 15◦ Celsius sind 59◦ Fahrenheit 97 98 Regel 1: Präzedenz Regel 2: Assoziativität Multiplikative Operatoren (*, /, %) haben höhere Präzedenz ("binden stärker") als additive Operatoren (+, -) Arithmetische Operatoren (*, /, %, +, -) sind linksassoziativ: bei gleicher Präzedenz erfolgt Auswertung von links nach rechts Beispiel Beispiel 9 * celsius / 5 + 32 9 * celsius / 5 + 32 bedeutet bedeutet (9 * celsius / 5) + 32 ((9 * celsius) / 5) + 32 99 100 Regel 3: Stelligkeit Klammerung Unäre Operatoren +, - vor binären +, -. Jeder Ausdruck kann mit Hilfe der Assoziativitäten Beispiel Präzedenzen 9 * celsius / + 5 + 32 Stelligkeiten (Anzahl Operanden) bedeutet der beteiligten Operatoren eindeutig geklammert werden. 9 * celsius / (+5) + 32 101 102 Ausdrucksbäume Auswertungsreihenfolge Klammerung ergibt Ausdrucksbaum "Von oben nach unten" im Ausdrucksbaum 9 * celsius / 5 + 32 (((9 * celsius) / 5) + 32) 9 celsius 5 32 9 * celsius 5 32 * / / + + 103 104 Ausdrucksbäume – Notation Typsystem Üblichere Notation: Wurzel oben Java hat ein statisches Typsystem: 9 * celsius / 5 + 32 Alle Typen müssen deklariert werden Falls möglich wird Typisierung wird vom Compiler geprüft . . . . . . ansonsten zur Laufzeit + 32 / Fail-fast Fehler im Programm werden oft schon vom Compiler gefunden Verständlicher Code 5 * 9 Vorteil eines statischen Typsystems celsius 105 106 Typfehler Explizite Typkonvertierung Beispiel Beispiel int pi_ungenau; float pi = 3.14f; int pi_ungenau; float pi = 3.14f; pi_ungenau = pi; pi_ungenau = (int) pi; Compiler Fehler: Explizite Typkonvertierung mit Typecasting: (typ) Statisch typkorrekt, Compiler happy ./Root/Main.java:12: error: incompatible types: possible lossy conversion from float to int pi_ungenau = pi; ^ Laufzeitverhalten: Je nach Situation Hier: Genauigkeitsverlust: 3.14 ⇒ 3 107 Kann das Programm zur Laufzeit zum Absturz bringen! 108 Typkonversion bei binären Operationen Bei einer binären Operation mit numerischen Operanden von verschiedenem Typ werden die Operanden nach folgenden Regeln konvertiert Implizite Konversion Expliziter Cast Typ Konvertierung - Anschaulich für Ganzzahlen byte short int long Haben beide Operanden denselben Typ, findet keine Konversion statt Ist einer der Operanden double, so wird der andere nach double konvertiert Ist einer der Operanden float, so wird der andere nach float konvertiert Ist einer der Operanden long, so wird der andere nach long konvertiert Potentieller Informationsverlust bei explizitem Cast, da weniger Speicher zur Verfügung. Ansonsten: Beide Operanden werden nach int konvertiert 109 110 Celsius zu Fahrenheit: Typanalyse Celsius zu Fahrenheit: Typanalyse Welcher Typ hat das Ergebnis? Besser: Berechnung und Ergebnis als float 9 * celsius / 5 int int int + 32 9f int * celsius / 5 float int int + int 32 int float int float int float 111 112 Anweisungen (Statements) Anweisungenarten Eine Anweisung ist . . . Gültige Anweisungen sind: vergleichbar mit einem Satz in der natürlichen Sprache. eine komplette Ausführungseinheit. immer mit einem Semikolon abgeschlossen. Wertzuweisungen Inkrement / Dekrement Ausdrücke Methodenaufrufe Objekterzeugungs-Ausdrücke (noch nicht gesehen) Beispiel f = 9f ∗ celsius / 5 + 32 ; 113 Anweisungenarten 114 Blöcke Ein Block ist . . . eine Gruppe von Anweisungen überall erlaubt wo Anweisungen erlaubt sind durch geschweiften Klammern markiert Beispiele aValue = 8933.234; // Wertzuweisung aValue++; // Inkrement { Anweisung Anweisung System.out.println("Awesome"); // Methodenaufruf } 115 ... 116 Kontrollstrukturen Kontrollstrukturen - Sequenz Die Abfolge der Ausführung eines Programms wird durch Anweisungen gesteuert. Beispiel Im einfachsten Fall: int fahrenheit = 9f ∗ celsius / 5 + 32; System.out.println("Fahrenheit: " + fahrenheit); Sequenz: Lineare Abfolge von Anweisungen: Anweisung Anweisung 118 117 Kontrollstrukturen - If Anweisung optional Bedingung: Boolsche Ausdrücke Ein Ausdruck der zu true oder false ausgewertet wird. Verwendet boolschen Operatoren in zusammengesetzten Ausdrücken. if ( Bedingung ) Anweisung else Anweisung Beispiele scanner.hasNext() // Hat es noch ein Zeichen? x > 3 || y > 3 119 // Ist x oder y groesser 3? 120 Vergleichsoperatoren Vergleichsoperatoren Infix Notation: x op y mit folgenden Operatoren op: < > <= >= == != Beispiele x >= 5 Nicht zu verwechseln mit Zuweisungsoperator “=” // ergibt true, falls x groesser oder gleich // 5 ist, ansonsten false a < b == b > a Angewandt auf zwei vergleichbare Operanden Resultat ist vom Typ boolean <, >, <= und >= binden stärker als == und != // Kommutativgesetz fuer Vergleiche 121 Boolsche Binäre Operatoren 122 Shortcut Evaluation Infix Notation: x op y mit folgenden Operatoren Wie wird dieser Ausdruck ausgewertet? ... && : Konjunktion (logisches “und”) || : Disjunktion (logisches “oder”) d > 0 && n/d > 1 Präzedenz: ... im Fall von d == 0 ? && vor || Beide binden schwächer als Vergleichsoperatoren 123 124 Shortcut Evaluation Shortcut Evaluation ⇒ Lazy Evaluation Annahme: d == 0 Annahme: d == 0 Problem: Die Auswertung des rechten Operandes würde zu einer Division durch 0 führen. Lösung: Faule Auswertung! Nur Auswerten was wirklich nötig ist. ⇒ Solche Programmfehler führen zum Abbruch der Auswertung! ⇒ d > 0 && irgend_etwas ⇒ 125 Boolscher unärer Operator: Negation false && irgend_etwas false Shortcut-Evaluation: Berechnung des Ausdrucks abbrechen sobald Ergebnis feststeht. 126 Boolscher unärer Operator: Negation Beispiel !(d > 0) || n/d == 0 Prefix Notation: ! b Die Negation binden stärker als alle anderen boolschen Operatoren, inklusive Vergleichsoperatoren 127 128 Kontrollstrukturen - Verwendung von Blöcken Kontrollstrukturen - Verwendung von Blöcken In Kontrollstrukturen sollten immer Blöcke verwendet werden.4 if ( Bedingung ) { Anweisung } else if ( Bedingung ){ Anweisung } else { Anweisung } 4 Wir Beispiele if (anzahl > 0) mean = sum / anzahl; ssq = sumsq / anzahl; System.out.println(ssq); weichen von dieser Regel sporadisch aus Gründen des Platzmangels auf übersichtlichen Folien ab. 130 129 Kontrollstrukturen - Verwendung von Blöcken Kontrollstrukturen: Schleifen Beispiele Es gibt mehrere Schleifen-Anweisungen if (anzahl > 0) { mean = sum / anzahl; } ssq = sumsq / anzahl; System.out.println(ssq); while do . . . while for und noch weitere Konstrukte (kommen später) 131 132 Kontrollstrukturen - While Schleife Kontrollstrukturen - While Schleife Beispiele int num = 143; int factor = 2; while ( Bedingung ) Anweisung while (num % factor != 0){ factor++; } System.out.println(factor + "|" + num); 134 133 Kontrollstrukturen - Do . . . While Schleife Kontrollstrukturen - Do . . . While Schleife Beispiele Scanner scanner = new Scanner(System.in); String password; do{ System.out.print("enter magic word:"); password = scanner.next(); } while (!password.equals("geheim")); System.out.println("Door open."); scanner.close(); do Anweisung while ( Bedingung ) 135 136 Kontrollstrukturen - For Schleife Kontrollstrukturen - Do . . . While Schleife Beispiele for ( Initialisierung ; Bedingung ; Fortschritt ) Anweisung ⇔ for (int x = 1; x <= 128; x ∗= 2) { System.out.println("x= " + x); } ⇔ Initialisierung while ( Bedingung ) { Anweisung Fortschritt } int x = 1; while (x <= 128){ System.out.println("x= " + x); x ∗= 2; } 138 137 Ein Beispiel: Monte Carlo Simulation π schätzen mit Monte Carlo Simulation Kreisfläche π = Fläche des Quadrates 4 Monte Carlo Simulation: Verwendung des Zufalls zum Lösen von Problemen. Breites Anwendungsfeld in der angewandten Mathematik und sämtlichen Natur- und Ingenieurswissenschaften. Idee: Simuliere Zufallsvariable mit Gleichverteilung auf dem Einheitsquadrat [0, 1] × [0, 1]. Anzahl Treffer · 4 ≈ π. Anzahl Versuche 139 y 1 Kein Treffer! Treffer! −1 1 x −1 140 Aufgabe π schätzen mit Monte Carlo Simulation public class Pi { public static void main(String[] args){ for (int trials = 1; trials <= 4096; trials∗=2){ int hits = 0; for (int i = 0; i<trials; ++i){ double x = Math.random(); double y = Math.random(); if (x ∗ x + y ∗ y <= 1){ hits++; } } double pi = (double)hits / trials ∗ 4; System.out.println("trials=" + trials + ", pi=" + pi); } } } Experiment: Schätze π mit obigem Monte-Carlo Verfahren Führe das Experiment durch für Anzahl Versuche 1, 2, 4, ... , 4096 Jeweils Ausgabe der Anzahl Versuche und der Schätzung von π . Hinweis: eine auf [0, 1) uniformverteilte Pseudo-Zufallszahl bekommt man mit Math.random(). 141 142