Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Die Funktionsbibliothek
10 Threads und nebenläufige Programmierung
11 Raum und Zeit
12 Datenstrukturen und Algorithmen
13 Dateien und Datenströme
14 Die eXtensible Markup Language (XML)
15 Grafische Oberflächen mit Swing
16 Grafikprogrammierung
17 Netzwerkprogrammierung
18 Verteilte Programmierung mit RMI und Web-Services
19 JavaServer Pages und Servlets
20 Applets
21 Midlets und die Java ME
22 Datenbankmanagement mit JDBC
23 Reflection und Annotationen
24 Logging und Monitoring
25 Sicherheitskonzepte
26 Java Native Interface (JNI)
27 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Stichwort
Download: - ZIP, ca. 12,5 MB
Buch bestellen
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> /Java-Insel | vor >>
Java ist auch eine Insel von Christian Ullenboom Programmieren mit der Java Standard Edition Version 6
Java ist auch eine Insel 7., aktualisierte Auflage geb., mit DVD (November 2007) 1.492 S., 49,90 Euro Galileo Computing ISBN 978-3-8362-1146-8 |
| 12 Datenstrukturen und Algorithmen
|  | 12.1 Datenstrukturen und die Collection-API
|  |  | 12.1.1 Designprinzip mit Schnittstellen, abstrakten Klassen, konkreten Klassen
|  |  | 12.1.2 Die Basis-Schnittstellen Collection und Map
|  |  | 12.1.3 Das erste Programm mit Container-Klassen
|  |  | 12.1.4 Die Schnittstelle Collection
|  |  | 12.1.5 Schnittstellen, die Collection erweitern, und Map
|  |  | 12.1.6 Konkrete Container-Klassen
|  |  | 12.1.7 Welche Klasse nehmen?
|  |  | 12.1.8 Generische Datentypen in der Collection-API
|  |  | 12.1.9 Die Schnittstelle Iterable und das erweiterte for
|  | 12.2 Mit einem Iterator durch die Daten wandern
|  |  | 12.2.1 Die Schnittstellen Enumeration und Iterator
|  |  | 12.2.2 Iteratoren von Sammlungen und das erweiterte for
|  |  | 12.2.3 Fail-Fast Iterator und die ConcurrentModificationException
|  | 12.3 Listen
|  |  | 12.3.1 ArrayList oder LinkedList? Speicherung im Feld oder in einer verketteten Liste
|  |  | 12.3.2 Die Schnittstelle List
|  |  | 12.3.3 ArrayList
|  |  | 12.3.4 LinkedList
|  |  | 12.3.5 Der Feld-Adapter Arrays.asList()
|  |  | 12.3.6 toArray() von Collection verstehen – die Gefahr einer Falle erkennen
|  |  | 12.3.7 Primitive Elemente in den Collection-Datenstrukturen
|  | 12.4 Vergleichen von Objekten
|  |  | 12.4.1 Die Schnittstellen Comparator und Comparable
|  |  | 12.4.2 Algorithmen mit Such- und Sortiermöglichkeiten
|  |  | 12.4.3 Den größten und kleinsten Wert einer Collection finden
|  |  | 12.4.4 Sortieren
|  | 12.5 Mengen (Sets)
|  |  | 12.5.1 HashSet
|  |  | 12.5.2 TreeSet – die Menge durch Bäume
|  |  | 12.5.3 LinkedHashSet
|  | 12.6 Stack (Kellerspeicher, Stapel)
|  |  | 12.6.1 Die Methoden von Stack
|  |  | 12.6.2 Ein Stack ist ein Vector – aha!
|  | 12.7 Queues (Schlangen) und Deques
|  |  | 12.7.1 Die Schnittstelle Queue
|  |  | 12.7.2 Blockierende Queues und Prioritätswarteschlangen
|  |  | 12.7.3 Deque-Klassen
|  | 12.8 Assoziative Speicher
|  |  | 12.8.1 Die Klassen HashMap und TreeMap
|  |  | 12.8.2 Einfügen und Abfragen der Datenstruktur
|  |  | 12.8.3 Die Bedeutung von equals(), hashCode() und IdentityHashMap
|  |  | 12.8.4 Elemente im Assoziativspeicher müssen unveränderbar bleiben
|  |  | 12.8.5 Aufzählungen und Sichten auf den Assoziativspeicher
|  |  | 12.8.6 Der Gleichheitstest, Hash-Wert und Klon einer Hash-Tabelle
|  |  | 12.8.7 Die Arbeitsweise einer Hash-Tabelle
|  |  | 12.8.8 Multi-Maps
|  | 12.9 Die Properties-Klasse
|  |  | 12.9.1 Properties setzen und lesen
|  |  | 12.9.2 Properties verketten
|  |  | 12.9.3 Eigenschaften ausgeben
|  |  | 12.9.4 Hierarchische Eigenschaften
|  |  | 12.9.5 Properties speichern
|  |  | 12.9.6 Klassenbeziehungen: Properties und Hashtable
|  | 12.10 Algorithmen in Collections
|  |  | 12.10.1 Listenoperationen: Ersetzen, Kopieren, Füllen, Umdrehen, Rotieren, Durchmischen
|  |  | 12.10.2 Mit der Halbierungssuche nach Elementen fahnden
|  |  | 12.10.3 Nicht-änderbare Datenstrukturen
|  |  | 12.10.4 Häufigkeit eines Elements
|  |  | 12.10.5 nCopies()
|  |  | 12.10.6 Singletons
|  | 12.11 Synchronisation der Datenstrukturen
|  |  | 12.11.1 Lock-Free-Algorithmen aus java.util.concurrent
|  |  | 12.11.2 Wrapper zur Synchronisation
|  |  | 12.11.3 CopyOnWriteArrayList und CopyOnWriteArraySet
|  | 12.12 Die Klasse BitSet für Bitmengen
|  |  | 12.12.1 Ein BitSet anlegen, füllen und erfragen
|  |  | 12.12.2 Mengenorientierte Operationen
|  |  | 12.12.3 Funktionsübersicht
|  |  | 12.12.4 Primzahlen in einem BitSet verwalten
## 12.9 Die Properties-Klasse Die Klasse Properties ist eine Sonderform der Assoziativspeicher, bei der Schlüssel-Werte-Paare immer vom Typ String sind. Da sich die Einträge in einer Datei speichern und wieder auslesen lassen, können auf diese Weise fest verdrahtete Zeichenketten aus dem Programmtext externalisiert werden, sodass sich die Werte auch ohne Neuübersetzung bequem verändern lassen. ### 12.9.1 Properties setzen und lesen Die Funktion setProperty(String, String) fügt dem Properties-Objekt ein Schlüssel/Wertepaar hinzu. Um später wieder an den Wert zu kommen, wird getProperty(String) mit dem Schlüssel aufgerufen und liefert dann – wenn beide Zeichenketten vorher verbunden wurden – den Wert.
    Properties props = new Properties();
    props.setProperty( "User", "King Karl" );
    props.setProperty( "Version", "" + 0.02 );
    System.out.println( props.getProperty("User") );      // King Karl
    System.out.println( props.getProperty("Passwort") );  // null
### 12.9.2 Properties verketten Properties-Objekte lassen sich hierarchisch verbinden, sodass im Fall einer erfolglosen Suche nach einem Schlüssel das Properties-Objekt die Anfrage an ein übergeordnetes Properties-Objekt weiterleitet; das Eltern-Properties-Objekt wird einfach im Konstruktor übergeben. Listing 12.25 com/tutego/insel/util/map/PropertiesDemo.java. main()
    Properties defaultProperties = new Properties(),
               userProperties    = new Properties( defaultProperties );
Die Zeilen erzeugen zwei Properties-Objekte. Obwohl am Anfang beide leer sind, werden doch die in defaultProperties hinzugefügte Einträge auch in userProperties sichtbar sein. Im folgenden ist abzulesen, wie userProperties einen Eintrag überschreibt.
    defaultProperties.setProperty( "User", "C.Ullenboom" );
    defaultProperties.setProperty( "Password", "(nicht gesetzt)" );
    userProperties.setProperty( "Password", "SagIchNet" );
Zuerst durchsucht ein Property-Exemplar die eigene Datenstruktur. Liefert diese keinen Eintrag oder keinen Wert vom Typ String, so wird das im Konstruktoraufruf angegebene Property-Objekt durchsucht. Auf diese Weise lassen sich mehrstufige Hierarchien von Property-Verzeichnissen konstruieren. Ein list() auf die defaultProperties beziehungsweise userProperties ergibt die Ausgabe:
    -- listing properties --
    Password=(nicht gesetzt)
    User=C.Ullenboom
    -- listing properties --
    Password=SagIchNet
    User=C.Ullenboom
    class java.util.Properties
    extends Hashtable<Object,Object>
Properties() Erzeugt ein leeres Properties-Objekt ohne Schlüssel und Werte. Properties( Properties defaults ) Erzeugt ein leeres Properties-Objekt, das bei Anfragen auch auf die Einträge in dem übergebenen Properties-Objekt zurückgreift. String getProperty( String key ) Sucht in den Properties nach der Zeichenkette key als Schlüssel und liefert den zugehörigen Wert. Durchsucht auch übergeordnete Properties-Objekte. String getProperty( String key, String default ) Sucht in den Properties nach der Zeichenkette key als Schlüssel und liefert den zugehörigen Wert. Ist der Schlüssel nicht vorhanden, wird der String default zurückgegeben. Object setProperty( String key, String value ) Trägt Schlüssel und Wert im Properties-Exemplar ein. Existiert der Schlüssel schon, wird er überschrieben. Mitunter verdeckt der Schlüssel den Wert der Property in der übergeordneten Property. ### 12.9.3 Eigenschaften ausgeben Die list()-Methode wandert durch die Daten eines Properties-Exemplars und schreibt sie in einen PrintStream oder PrintWriter. Das sind Datenströme, denen wir uns näher im Eingabe- und Ausgabekapitel widmen wollen. Eine Ausgabe auf dem Bildschirm erhalten wir mit list(System.out). Schlüssel und Werte trennt ein Gleichheitszeichen. Die Ausgabe über list() ist gekürzt, denn ist ein Wert länger als 40 Zeichen, wird er abgekürzt. Den Paaren geht eine Kopfzeile der Art -- listing properties -- voran. Es ist wichtig zu verstehen, dass durch die Art der Speicherung (ein Assoziativspeicher auf Basis des Hashings) die Ausgabe unsortiert erfolgt.
    class java.util.Properties
    extends Hashtable<Object,Object>
void list( PrintStream out ) Listet die Properties auf dem PrintStream aus. void list( PrintWriter out ) Listet die Properties auf dem PrintWriter aus. ### 12.9.4 Hierarchische Eigenschaften Leider kann eine Eigenschaften-Datei nicht segmentiert werden, wie etwa alte Windows-INI-Dateien dies machen. Die Alternative besteht darin, hierarchisch benannte Eigenschaften zu erzeugen, indem eine Zeichenkette vor jeden Schlüssel gesetzt wird. Um zum Beispiel einen Schlüssel User einmal unter Private und einmal unter Public zu halten, lässt sich die Eigenschaft Private.User und Public.User einsetzen. Doch leider tauchen sie nach dem Speichern quer gewürfelt in der Datei auf, weil ein Assoziativspeicher keine Sortierung besitzt. ### 12.9.5 Properties speichern Während die list()-Funktion nur für Testausgaben gedacht ist, dient store() zum Speichern und load() zum Laden eines Properties-Objekts in einer ASCII-Datei, die Schlüssel und Werte mit einem Gleichheitszeichen trennt. Das folgende Beispiel initialisiert ein Properties-Objekt mit den Systemeigenschaften und fügt dann einen Wert hinzu. Anschließend macht store() die Daten persistent, load() liest sie wieder und list() gibt die Eigenschaften auf dem Bildschirm aus. Listing 12.26 com/tutego/insel/util/map/SaveProperties.java, main()
    Writer writer = null;

    try
    {
      writer = new FileWriter( "properties.txt" );

      Properties p1 = new Properties( System.getProperties() );
      p1.setProperty( "MeinNameIst", "Forrest Gump" );
      p1.store( writer, "Eine Insel mit zwei Bergen" );

      Reader reader = new FileReader( "properties.txt" );

      Properties p2 = new Properties();
      p2.load( reader );
      p2.list( System.out );
    }
    catch ( IOException e )
    {
      e.printStackTrace();
    }
    finally
    {
      try { writer.close(); } catch ( IOException e ) { }
    }
    class java.util.Properties
    extends Hashtable<Object,Object>
void load( InputStream inStream ) Lädt eine Properties-Liste aus einem Eingabestrom. void store( OutputStream out, String header ) Speichert die Properties-Liste mit Hilfe des Ausgabestroms ab. Am Kopf der Datei wird eine Kennung geschrieben, die im zweiten Argument steht. Die Kennung darf null sein. void Enumeration<?> propertyNames() Liefert eine Enumeration von allen Schlüsseln in der Property-Liste inklusive der Standardwerte aus übergeordneten Properties. #### Properties im XML-Format speichern Die Properties-Klasse kann die Eigenschaften im XML-Format speichern und laden. Zum Speichern dient die Funktion storeXML() und zum Laden dient loadFromXML(). Die XML-Dateien haben ein spezielles Format, wie es der Einzeiler System.getProperties().storeToXML(System.out, ""); zeigt:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    <comment></comment>
    <entry key="java.runtime.name">Java(TM) 2 Runtime Environment, Standard Edition
    </entry>
    <entry key="java.vm.vendor">Sun Microsystems Inc.</entry>
    <entry key="java.vendor.url">http://java.sun.com/</entry>
    <entry key="path.separator">;</entry>
    ...
    <entry key="sun.desktop">windows</entry>
    <entry key="sun.cpu.isalist">pentium i486 i386</entry>
    </properties>
Die Methode loadFromXML() liest aus einem InputStream und löst im Fall eines fehlerhaften Dateiformats eine InvalidPropertiesFormatException aus. Beim Speichern kann so ein Fehler natürlich nicht auftreten. Und genauso, wie bei store() ein OutputStream mit einem Kommentar gespeichert wird, macht das auch storeToXML(). Die Funktion ist mit einem zusätzlichen Parameter überladen, der eine XML-Kodierung erlaubt. Ist der Wert nicht gesetzt, so ist die Standardkodierung UTF-8. ### 12.9.6 Klassenbeziehungen: Properties und Hashtable Die Properties-Klasse ist eine Erweiterung von Hashtable, weil die Speicherung der Einstellungsdaten in dieser Datenstruktur erfolgt. Ein Properties-Objekt erweitert die Hash-Tabelle um die Möglichkeit, die Schlüssel-Werte-Paare in einem festgelegten Format aus einer Textdatei beziehungsweise einem Datenstrom zu laden und wieder zu speichern. Doch gerade weil Hashtable erweitert wird, sind auch alle Methoden der Klasse Hashtable auf ein Properties-Objekt anwendbar. Das ergibt nicht für alle Methoden Sinn und ist auch nicht in jedem Fall problemlos. Dass Properties eine Unterklasse von Hashtable ist, ist ähnlich fragwürdig wie die Vererbungsbeziehung von Stack als Unterklasse von Vector. So ist ein Augenmerk auf die put()-Funktion zu legen. Sie gibt es in der Klasse Properties nicht, denn put() wird von Hashtable geerbt. Wir sollten sie auch nicht verwenden, da es über sie möglich ist, Objekte einzufügen, die nicht vom Typ String sind. Das gleiche Argument könnte für get() gelten, doch sprechen zwei Dinge dagegen: Zum einen, dass wir beim get() aus einem Hashtable-Objekt immer ein Object-Objekt bekommen und daher meistens eine Typanpassung benötigen, und zum anderen durchsucht diese Methode lediglich den Inhalt des angesprochenen Properties-Exemplars. getProperties() arbeitet da etwas anders. Nicht nur, dass der Rückgabewert automatisch ein String ist, sondern auch, dass getProperties() übergeordnete Properties-Objekte mit durchsucht, die zum Beispiel Standardwerte speichern. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.
Name |
E-Mail |
Ihr Kommentar |
<< zurück | <top> | vor >>

Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de