Weitere Grundlegendende Programmierkonzepte in Java
Website: | Hamburg Open Online University |
Kurs: | Programmieren mit Java |
Buch: | Weitere Grundlegendende Programmierkonzepte in Java |
Gedruckt von: | Gast |
Datum: | Sonntag, 24. November 2024, 03:11 |
Beschreibung
Hier erfährst Du, wie du Deine entwickelten Inhalte lesen und speichern kannst und lernst Methoden, Zahlen und Arrays kennen.
Dateien lesen und schreiben
import java.io.File; import java.io.PrintWriter;
Danach kann es losgehen.
File datei = new File("datei.txt"); PrintWriter printWriter = new PrintWriter(datei); printWriter.print(text); printWriter.close();
Der PrintWriter legt eine neue Datei an, falls diese noch nicht existiert. Sollte schon eine Datei existieren, so wird sie überschrieben.
Als Nächstes wollen wir den Inhalt unserer Datei wieder einlesen. Hier können wir wieder die Scanner-Klasse verwenden. Dieses Mal übergeben wir aber nicht System.in als Parameter sondern unsere File-Instanz. Das alleine reicht aus um einen Scanner zu erzeugen, der aus einer Datei ließt.
Es ist hierbei wichtig, dass die Datei bereits existiert, da das Programm sonst abstürzt. Dafür verwenden wir die datei.exists() Methode der File Klasse.
String text = ""; File datei = new File("datei.txt"); if (datei.exists()) { Scanner scanner = new Scanner(datei); while (scanner.hasNextLine()) { text += scanner.nextLine() + "\n"; } scanner.close(); }
Mit der Methode scanner.hasNextLine() kann geprüft werden, ob es weitere Zeilen in der Datei gibt. Wenn ja, kann mit der Methode scanner.nextLine() die Zeile gelesen werden.
Mit diesem neuen Wissen können wir nun unser Tagebuch erheblich verbesser:
import java.io.File; import java.io.PrintWriter; import java.util.Scanner; public class Tagebuch { public static void main(String[] args) throws Exception { System.out.println("Wie heißt du?"); Scanner scanner = new Scanner(System.in); String name = scanner.next(); if (name.equals("Jan")) { System.out.println("Hallo " + name + "!"); String text = ""; // Bisherige Einträge laden File datei = new File("tagebuch-" + name + ".txt"); if (datei.exists()) { Scanner scnr = new Scanner(datei); while (scnr.hasNextLine()) { text += scnr.nextLine() + "\n"; } scnr.close(); } System.out.println("Geladener Text: " + text); System.out.println("Bitte Text eingeben. Zum Beenden 'quit' eingeben."); // Schleife zum Einlesen des Textes while (true) { String eingabe = scanner.next(); // "quit" beendet die Schleife if (eingabe.equals("quit")) { break; } text += eingabe; } System.out.println("Eingegeben wurde: " + text); // Neuen Tagebuchinhalt speichern PrintWriter printWriter = new PrintWriter(datei); printWriter.print(text); printWriter.close(); } else { System.out.println("Der Benutzer ist abgelehnt."); } scanner.close(); } }
Methoden bzw. Funktionen
public static void schreibeSumme(int zahl1, int zahl2) { System.out.println(zahl1 + zahl2); }
Ein Aufruf dieser Methode könnte z.B. so aussehen schreibeSumme(1, 2);
Anstatt die Summe auszugeben kann sie auch zurückgegeben werden um sie im weiteren Programmablauf verwenden zu können. Hierfür muss der Rückgabetyp der Methode richtig definiert werden und es muss ein “return” definiert werden. Mit dem “return” wird festgelegt, welcher Wert zurück gegeben werden soll.
public static void berechneSumme(int zahl1, int zahl2) { return zahl1 + zahl2; }
Jeder Code-Pfad soll mit einem “return” enden. Code, der nach einem “return” folgt, wird nicht mehr ausgeführt.
Als letzter Teil der Signatur kann eine ‘throws’ Anweisung mit einem Fehlerdatentyp angegeben werden. Ersteinmal soll es ausreichen bei jeder Methodendeklaration “throws Exception” anzugeben. Wir werden im Abschnitt “Fehlerbehandlung” darauf genauer eingehen.
Wir haben jetzt alles was wir brauchen um unser Beispiel in mehrere Methoden aufzuteilen. Unsere Main-Methode soll dabei nur noch die einzelnen Aktionen starten. Als erstes prüft sie den Namen des Benutzers. Erst, wenn der Name der Richtige ist, werden Daten aus der Datei geladen. Dies soll in der Methode leseAusDatei() geschehen. Sie bekommt als Parameter eine Datei. Existiert die Datei so wird der Inhalt zurückgegeben, sonst nur ein leerer String.
Die zweite Methode leseEingaben() soll den Nutzer auffordern etwas einzugeben und die Eingaben zurück geben. Die dritte Methode schreibeDaten() gibt nichts zurück. Sie speichert den übergebenen String in die Datei. Dieses Programm kann wie folgt umgesetzt werden:
import java.io.File; import java.io.PrintWriter; import java.util.Scanner; public class Tagebuch { public static void main(String[] args) throws Exception { System.out.println("Wie heißt du?"); Scanner scanner = new Scanner(System.in); String name = scanner.next(); if (name.equals("Jan")) { System.out.println("Hallo " + name + "!"); File datei = new File("tagebuch-" + name + ".txt"); String text = leseAusDatei(datei); text .= leseEingaben(scanner); schreibeDaten(text, datei); } else { System.out.println("Der Benutzer ist abgelehnt."); } scanner.close(); } public static String leseAusDatei(File datei) throws Exception { String text = ""; if (datei.exists()) { Scanner scnr = new Scanner(datei); while (scnr.hasNextLine()) { text += scnr.nextLine() + "\n"; } scnr.close(); } System.out.println("Geladener Text: " + text); return text; } public static String leseEingaben(Scanner scanner) { String text = ""; System.out.println("Bitte Text eingeben. Zum Beenden 'quit' eingeben."); // Schleife zum Einlesen des Textes while (true) { String eingabe = scanner.next(); // "quit" beendet die Schleife if (eingabe.equals("quit")) { break; } text += eingabe; } System.out.println("Eingegeben wurde: " + text); return text; } public static void schreibeDaten(String text, File datei) throws Exception { PrintWriter printWriter = new PrintWriter(datei); printWriter.print(text); printWriter.close(); } }
Zahlen und Operatoren
Im Bisherigen verlauf dieser Einheit haben wir uns nur mit Zeichenketten
und deren Ein- und Ausgabe auf Konsole und in Dateien beschäftigt. Wir
können durch Zeichenketten alle möglichen Dinge lesbar darstellen.
Leider haben sie aber viele Einschränkungen, da der Computer nicht
verstehen kann, was dort abgebildet wird. Um z.B. Berechnungen
durchführen zu können, wollen wir im nächsten Abschnitt weitere
Datentypen für Zahlen in den Fokus nehmen. Für diese Datentypen haben
wir in unserem Tagebuch keine Verwendung, sie sind aber elementarer
Bestandteil der Programmiersprache und sollen daher nicht fehlen.
Datentypen für Zahlen
float f = 2345678.88f; System.out.println(f); // zeigt 2345679.0 double d = 2345678.88; System.out.println(d); // zeigt 2345678.88
Diese Datentypen für Zahlen haben alle gemeinsam, dass sie automatisch mit 0 initialisiert werden, wenn wir dies nicht explizit anders tun.
Operatoren
Als nächstes wollen wir uns die vielen Möglichkeiten anschauen, die uns die Operatoren in Java zur Verfügung stellen. Operatoren verbinden ein oder zwei Aussagen zu einer neuen. Dabei ist genau definiert, welcher Operator welches Ergebnis liefern muss. Es ist aber auch definiert, welche Datentypen er als Eingabe akzeptiert.
= (Wertzuweisungsoperator)
+ (Additionsoperator)
Der Additionsoperator addiert zwei Zahlen miteinander und gibt das Ergebnis zurück.Es ist nicht erforderlich, dass die beiden Zahlen vom selben Typ sind. Der Rückgabetyp ist immer so klein wie möglich aber so groß wie nötig.
Einige Beispiele:
int + int = int
int + long = long
int + float = float
int + double = double
long + float = float
long + double = double
float + double = double
Wir hatten bereits für den Typ String gelernt, dass der Additionsoperator als Konkatenation verstanden wird also als Aneinanderreihen der Strings. Das selbe geschieht, wenn man ein String mit einer Zahl “addiert” System.out.println("Es gibt " + 8 + " Planeten in unserem Sonnensystem.");.
- (Subtraktionsoperator)
Der Subtraktionsoperator subtrahiert die zweite Eingabezahl von der Ersten und gibt das Ergebnis zurück.Für den Rückgabetyp gelten die selben Bedingungen wie bei der Addition.
* (Multiplikationsoperator)
Der Multiplikationsoperator multipliziert zwei Zahlen und gibt das Ergebnis zurück.Für den Rückgabetyp gelten die selben Bedingungen wie bei der Addition.
/ (Divisionsoperator)
Der Divisionsoperator teilt die erste Eingabezahl durch die Zweite und gibt das Ergebnis zurück.
Für den Rückgabetyp gelten die selben Bedingungen wie bei der Addition. Man muss aber wissen, dass im Falle eines ganzzahligen Ergebnistyps die Stellen hinter dem Komma einfach verworfen werden. Beispielsweise ergibt int i = 3 / 2; das Ergebnis i = 1.
Die Division durch 0 ist wie in der Mathematik üblich nicht möglich. Das Programm stürzt mit einem Fehler ab. Dies gilt zumindest für die int 0 und die long 0. Eine Division durch double oder float 0.0 ergibt Unendlich, was als int ausgedrückt 2^31-1 ist.
% (Modulooperator)
Durch die Verwendung von Modulo erhalten wir den ganzzahligen Rest einer Division. Zum Beispiel ergibt int i = 3 / 2; das Ergebnis i = 1;.
Für den Rückgabetyp gelten die selben Bedingungen wie bei der Addition.
Vergleichsoperatoren
Scanner scanner = new Scanner(System.in); String a = "."; String b = a; String c = "."; String d = scanner.next(); // Wir geben nur einen . ein und drücken Enter. System.out.println(a == b); // ergibt true // Da wir b = a gesetzt haben, handelt es sich um den selben Speicher. System.out.println(a == c); // ergibt true // Der Compiler hat festgestellt, dass beide Strings gleich aussehen und lässt beide Variablen auf den selben Speicher zeigen. System.out.println(a == d); // ergibt false // Der Compiler hat einen neuen Speicherbereich vorgesehen, da er nicht wusste was eingegeben wird.
Für den Programmierer ist es oftmals nicht ersichtlich, welche Optimierungen der Compiler vornehmen wird und es ist für ihn meistens auch irrelevant. Wichtig ist, dass man den Operator nur einsetzt, wenn man weiß was er wirklich vergleicht und im Zweifel lieber die .equals()-Methode verwendet, welche meistens die erwarteten Ergebnisse bringt. Als dritte Gruppe wollen wir uns noch einmal die boolschen Operatoren anschauen.
! (Verneinungsoperator)
Durch eine Verneinung wird eine Wahrheitsaussage in das Gegenteil verwandelt.
&& (logisches Und)
Durch das logische Und werden zwei Wahrheitsaussagen verbunden. Nur, wenn beide der Aussagen wahr sind, ist das Ergebnis wahr.
|| (logisches Oder)
Das logische Oder liefert als Ergebnis wahr, wenn mindestens eine der zwei Wahrheitsaussagen wahr ist.
System.out.println( 2 + 3 * 4 ); // Ergebnis 14 System.out.println( (2 + 3) * 4 ); // Ergebnis 24
Konvertierung
long l = 1; // funktioniert int i = 1l; // Erzeugt einen Compilerfehler
System.out.println( (int)1.5 * 2 ); // Ergebnis 2 System.out.println((int)(1.5 * 2)); // Ergebnis 3
Arrays
int[] zahlen = new int[25]; for(int i = 0; i < zahlen.length; i++) { zahlen[i] = i + 1; }