Dieser Teil der Vorlesung verwendet das Skriptum als Unterlage, daher sind hier nur Beispielprogramme und einige Stichworte zu finden.
javac,
Laufzeitsystem java
Lebensdauer und Speicher von Variablen bei fib(3):
public static int fib(int n) {
if (n<2)
return n;
else
return fib(n-1)+fib(n-2);
}
Referenztypen behandeln wir später
Interessant ist dabei besonders java.lang und java.util.
Fakultät berechnen:
public class Fact { // Dateiname Fact.java
public static int fact(int n) {
if(n == 0) {
return 1;
} else {
return n * fact(n - 1);
}
}
public static void main(String[] args) {
System.out.println(fact(Integer.parseInt(args[0])));
}
}
Eingabe mit args beschränkt. Alternative: System.in.
Problem: Wie sollen Zeichen der Eingabe interpretiert werden? Lösung: Scanner
import java.util.Scanner;
public class Fact {
public static int fact(int n) {
/* ... */
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.println(i);
}
}
Fakultät von n! wird meist eher so berechnet, dass man bei 1 beginnend mit der nächst größeren Zahl multipliiert, bis man n erreicht.
10! = 1 * 2 * 3 * ... * 10
Als Programm: Beginne bei 1 und multipliziere auf, bis n erreicht wird.
public static int fact(int n) {
int i = 0;
int result = 1;
while(i <= n) {
result *= i;
i ++;
}
return result;
}
while-Schleife immer bei "Solange Bedingung, wiederhole".
Spezialfall von while-Schleife: For-Schleife mit Initialisierungsteil und Aktualisierungsteil.
Spezialfall von while-Schleife: For-Schleife mit Initialisierungsteil und Aktualisierungsteil.
public static int fact(int n) {
int result = 1;
for(int i = 0 ; i <= n ; i ++) {
result *= i;
}
return result;
}
Übungsaufgabe: Testen, ob eine Zahl eine Primzahl ist
Unterschied zu while: Wird mindestens 1x durchlaufen.
public static main(String[] args) {
Scanner sc = new Scanner(System.in);
do {
/* ... */
System.out.println("Noch einmal?");
} while(sc.next().equals("ja"));
}
Debuggen hilft beim Nachvollziehen des Programms. Je besser strukturiert das Programm, desto einfacher wird Debuggen. Debuggen ersetzt nicht den Designprozess!
Möglichkeiten zum Debuggen
Arrays sind Objekte, die aus mehreren Elementen - alle vom selben Datentyp - zusammengesetzt sind. Arrays sind Referenztypen, das heißt, Variablen vom Typ Array enthalten das Array nicht, sondern zeigen auf ein Array. Wie alle Objekte müssen Arrays angelegt werden.
public class ArrayTest {
public static void testSwapInts(int i0, int i1) {
int tmp = i0;
i0 = i1;
i1 = tmp;
}
public static void swapInts(int[] arr) {
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}
public static void main(String[] args) {
int i0 = 5;
int i1 = 6;
testSwapInts(i0, i1);
System.out.printf("%d, %d\n", i0, i1); // Keine Änderung.
int[] arr = new int[2]; // Erzeugt ein Array mit 10 Elementen.
arr[0] = 5; // Erstes Element hat immer Index 0.
arr[1] = 6;
// Alternative: int[] arr = new int[]{5, 6};
// Zugriff auf arr[2] fuehrt zu einem Fehler.
swapInts(arr);
// Neuer Schleifentyp: For-Each-Schleife. Gibt alle Elemente zurueck:
for(int e : arr) {
System.out.println(e);
}
/* Aequivalent zu
for(int j = 0; j < arr.length; j++) {
System.out.println(arr[j]);
}
*/
}
}
Übungsaufgabe: Sieb des Eratosthenes
Strings sind Zeichenketten, d.h., Datenstrukturen in denen man Text speichern kann.
Strings sind ein Referenztyp. Es gibt allerdings keine Methoden, mit denen man einen String inhaltlich ändern kann. Alle Methoden, die eine Zeichenkette zurückgeben, erzeugen eine neue Zeichenkette. Daher keine Seiteneffekte.
nur ein Element bei der Implementierung von Datenstrukturen. Eine Datenstruktur enthält Daten und Operationen auf den Daten. Beispiel: Stack auf der Basis von linked lists. Andere naheliegende Datenstrukturen mit verketteten Listen: Menge, Sequenz.
Implementierung von Stack (oder Queue) mit Array
Gleiches Interface, (fast) gleiches Verhalten, unterschiedliche Implementierung: abstrakter Datentyp
Gleiches Interface, teilweise unterschiedliches Verhalten. Dynamische Bindung von Methoden.
new).
abstract kennzeichnen), aber auch Methoden und
Variablen, man kann kein Exemplar davon machen, sonst wie Klasse.
new).
static Methoden: Aufruf mit methode(args)
Object"a"+b ist äquivalent zu "a"+b.toString();.
== vs. equals
Beachte: Zusammenhang zwischen equals und hashCode muss man selbst sicherstellen
Object hashCode
toString
IntStackA hashCode
toString
IntStackI hashCode
toString
Zweck: Kommunikation mit anderen Programmierern (oder auch mit dem zukünftigen Ich): Auf welche Teile der Klasse kann man sich verlassen, und welche Teile können sich ändern; kann ich z.B. die Datenrepräsentation von Array auf verkettete Liste ändern?
Gutes Design? Klassenzusammenhalt (Cohesion): Man kann isIncreasing() ohne weiteres aus der Klasse entfernen, also geringer Zusammenhalt.
Assertions, Invarianten
Testen (Skriptum 5.3). Black box test, white box test, unit test, integration test, regression test. "Tests können nur die Anwesenheit von Fehlern beweisen, nicht die Abwesenheit".
Debuggen (Skriptum 5.4) mittels Ausgabe-Anweisungen ("printf-Debugging"). Debuggen mit netbeans; bequemer, aber oft Zeitfresser.
Beweisen. Model Checking.
Containers, Collections
Iteratoren