»Programmieren«, WS 2006/2007 Nino Simunic M.A. Nino Simunic ([email protected]) Übungsblatt 12 Aufgabe 1 DOKUMENTENSUCHE Aufgabe Schreiben Sie eine ausführbare Klasse FindText mit zwei statischen, öffentlichen Methoden findStringInFile, welche die eigentliche Sucharbeit vornimmt. public static int findStringInFile(File file, String searchText) public static int findStringInFile(String filePath, String searchText) searchText ist der zu suchende Text im Dokument. Optional: Der Rückgabewert ist entweder die Anzahl der Treffer im Dokument oder -1, wenn die Datei nicht existiert. Geben Sie während der Suche bei Treffern die Zeile mit Zeile mit Treffer aus und stellen Sie dieser die Zeilennummer voran. Geben Sie am Ende der Suche auch die Anzahl der Treffer aus. Erwägen und implementieren Sie die Möglichkeit, dass via main-Methode die findStringInFile-Parameter ins Programm gelangen. Ferner sollen auch mehrere Dateinamen angegeben werden können: java FindText SUCHTEXT Dateiname1 Dateiname2 ..." Tipps API, Literatur, Übungsgruppenleiter konsultieren Stringvergleiche können unter anderem über die String-Methode indexOf() vorgenommen werden. Sie liefert einen Wert > -1 zurück, wenn das String-Argument im String enthalten ist: System.out.println("Hai".indexOf("ai")); // 1 System.out.println("Hai".indexOf("Fi")); // -1 Programmieren Nino Simunic M.A. Seite 1 Aufgabe 2 SERIALISIERUNG VON OBJEKTEN Einleitung Normale Java-Objekte sind »flüchtig«, das heißt, sie existieren nur so lange, wie das Programm bzw. die Java Virtual Machine läuft. Das ist natürlich unerwünscht, wenn die erzeugten Daten längerfristig benötigt werden. Es wäre demnach sehr nützlich, wenn die Objekte dauerhaft gespeichert und jederzeit wieder hergestellt werden könnten. Dieses Konzept wird Persistenz genannt. Die Serialisierung ermöglicht es, Java-Objekte als Byte-Streams zu schreiben und aus Byte-Streams Java-Objekte zu erstellen. So wird das Speichern von Java-Objekten in Dateien ermöglicht. Es ist aber ebenso gut möglich, mit Hilfe der Serialisierung Objekte über Netzwerkverbindungen zu versenden und beim Empfänger wiederherzustellen. Dies wird auch in Java RMI für die Kommunikation zwischen Client und Server benutzt. Im Paket java.io befinden sich die notwendigen Klassen und Interfaces, die die Serialisierung ermöglichen. Damit eine Klasse serialisierbar ist, muss sie das Interface java.io.Serializable implementieren. Mit Hilfe von ObjectOutputStream und ObjectInputStream können Objekte geschrieben und gelesen werden. Um ein Objekt in eine Datei zu schreiben, sind nur wenige Zeilen Code notwendig: FileOutputStream fos = new FileOutputStream("objekt"); ObjectOutputStream out = new ObjectOutputStream(fos); out.writeObject(dasObjekt); Um das Objekt anschließend wieder zu lesen, sind folgende Schritte notwendig: FileInputStream fis = new FileInputStream("objekt"); ObjectInputStream in = new ObjectInputStream(fis); MeineKlasse dasObjekt = (MeineKlasse)in.readObject(); Zu beachten ist hier, dass das Objekt auch als java.lang.Object wieder eingelesen wird. Es muss anschließend noch zu einem Objekt der richtigen Klasse gecastet werden. Mittels der Serialisierung werden alle Attribute einer Klasse gespeichert, die nicht mit dem Schlüsselwort transient gekennzeichnet sind. Aufgabe Implementieren Sie sie eine ausführbare Klasse TestSerial mit den Methoden readSerialized( String seriFile ) und writeSerialized( String seriFile ), welche eine Buch-HashMap serialisiert von/zu seriFile lesen und schreiben kann. Die Attribute der HashMap sind Buch-Objekte, die Werte der Attribute jeweils ein beliebiger Integer-Wert, welcher die Anzahl der Bücher im Lager repräsentieren soll. Falls Ihnen keine Bücher einfallen sollten: Titel: Per Anhalter durch die Galaxis Autor: Douglas Adams Verlag: Heyne Seitenzahl: 42 Titel: Das Restaurant am Ende des Universums Autor: Douglas Adams Verlag: Heyne Seitenzahl: 245 Titel: Das Parfüm Autor: Patrick Süskind Verlag: K.A. Seitenzahl: 324 Programmieren Nino Simunic M.A. Seite 2 Tipp Um über die Attribute und Werte einer HashMap zu iterieren, können Sie einen Iterator verwenden, welcher aus Sets operiert. Das Set erhalten Sie via keySet-Methode von HashMap. Dieses Set können Sie dann einem Iterator zuweisen. Wie bei Vector gilt für alle Elemente, dass sie vom Typ Object sind – Sie müssen beim Auslesen von Attributen also explizt casten. Beispiel: Sie wollen alle Schlüssel mit entsprechenden Werten ausgeben. HashMap testMap = new HashMap(); testMap.put("This", 12); testMap.put("and that", 99); Set keySet = testMap.keySet(); Iterator i = keySet.iterator(); while ( i.hasNext()) { String key = (String) i.next(); Integer value = (Integer) testMap.get(key); System.out.println("Key: " + key + " / Value: "+value); } Vorgehensweise: Sie iterieren über die assoziative Liste (die HashMap) über die eindeutigen Schlüssel. hasNext() ist solange wahr, wie Schlüssel vorhanden sind. Die Map merkt sich, welche bereits ‚dran’ waren. next() holt das nächste Element. Vorsicht: Weitere Aufrufe von next() sind möglich und würden das darauf folgende Element holen. Dies kann jedoch zu einer NullPointerException führen, falls keine (neuen) Schlüssel mehr existierten. Dies wird ja mit hasNext vorher überprüft, so dass nur einmal next() aufgerufen werden darf und sollte, um den Wert zwischenzuspeichern. Explizites Casten ist notwendig, da die Map-Elemente Daten vom Typ Object sind. Programmieren Nino Simunic M.A. Seite 3