Programmierkurs Java - Universität zu Lübeck

Werbung
Programmierkurs Java
Java Generics und Java API (1/2)
Prof. Dr. Stefan Fischer
Institut für Telematik, Universität zu Lübeck
https://www.itm.uni-luebeck.de/people/fischer
Datenstrukturen
• In vielen Sprachen (z.B. C) hat praktisch jedes Programm seine
eigenen Datentypen implementiert
• Probleme: viel unnötiger Code, Fehlerquelle, schwer auszutauschen,
jedes Programm war „einzigartig“  hohe Einarbeitungszeit
• Daher: Java stellt Standardtypen bereit
– Teil der Java Distribution
– Sog. „Java Collections Framework“ (java.util.*)
• Referenzen
– http://download.oracle.com/javase/tutorial/collections/
– http://download.oracle.com/javase/7/docs/api/
#2
Java Collections Framework (JCF)
• Stellt sog. Container-Klassen bereit
– Container nehmen andere Datentypen in sich auf
– Dynamische Datenstrukturen, die ihre Größe anpassen
• Zwei grundlegende Typen: Collection und Map
– Collection (java.util.Collection)  in dieser Vorlesung
• Listen, Mengen, Schlangen (Queues)
– Map für Assoziativspeicher (java.util.Map)
• Speichert <name, wert>-Tupel
#3
Java Collections Framework (JCF)
•
Interfaces legen den Funktionsumfang eines Containertyps fest
– z.B. das Interface Collection
•
Konkrete Klassen erben von diesen und implementieren die Funktion des
Containers
– Abstrakte Basisklassen dienen zur vereinfachten Implementierung konkreter
Klassen
•
Beispiel
Implementiert Interface „Collection“
Abstrakte Listenimplementierung
Konkret, Speicherung in Array
#4
Teil der Vererbungshierarchie
Collection
AbstractList
ArrayList
...
AbstractSet
Vector
TreeSet
...
HashSet
#5
Collection Interface
• Wichtige Methoden
–
–
–
–
–
–
boolean add(E e);
void clear();
boolean contains(Object o);
int size();
Iterator iterator();
...
• Was ist wohl ein Iterator?
– Später...
#6
Interface java.util.Collection
#7
Instanziierung einer Collection
• Beispiel: Verwendung einer Liste
– Zunächst Wahl einer Implementierung
– Dann Instanziierung
•Collection c = new ArrayList();
#8
Verwendung von Collection
import java.util.*;
public class NutzungVonCollection {
private static void test( Collection c ) {
for ( int i = 0; i < 5; i++ )
c.add( i );
System.out.println(“Ist leer? “ + c.isEmpty());
System.out.println(
“Anzahl Elemente: “ + c.size());
}
}
#9
Konzept der Iteratoren
• Dient dem Zugriff auf Elemente einer Collection
– Im einfachsten Fall kann man nur vorwärts von einem Element zum
nächsten gelangen
– Iterator iterator = collection.iterator();
• Zwei wesentliche Methoden eines Iterators
– boolean hasNext(): true, wenn es ein weiteres Element gibt
– Object next(): Liefert nächstes Objekt
• Beispiel: Iteration über Collection
next()
hasNext:
true
next()
hasNext:
true
1324
next()
hasNext:
true
234
next()
hasNext:
true
333
next()
hasNext:
true
445
next()
hasNext:
true
54343
next()
hasNext:
true
6434
next()
hasNext:
true
75
hasNext:
false
8345
#10
Verwendung von Iteratoren
• Vorsicht: nicht 2x next() aufrufen pro 1x hasNext()
– z.B. innerhalb der while-Schleife
#11
Verwendung von Iteratoren
• Oft besser: Referenz auf nächstes Objekt einer
Variable zuweisen
#12
Kürzere Variante: for-Schleife
• Iterationen über Collections lassen sich mit der
for-Schleife prägnant und kurz schreiben
– Initialisierung: Zuweisung einer Iterator-Referenz
– Bedingung: Prüfen auf hasNext();
– Inkrement: Nichts tun
#13
Noch kürzere Variante: foreach-Schleife
• Seit Java 1.5 gibt es noch eine weitere Schleife
– Speziell für die Iteration über Collections, Arrays, etc.
– Abkürzende Schreibweise, kann durch for-Schleife
ersetzt werden
– Möglich für alle Objekte, die das Interface „Iterable“
implementieren
– Also z.B. Collection
• Syntax:
– for(Typ variable : iterableObject )
statement;
#14
Das Interface „Iterable“
#15
Foreach und Collections
• Beispiel: Umwandlung einer for-Schleife in
eine foreach-Schleife
#16
Collections und ihre Daten
•
Beispiel
– c.add( new String(“1“) );
c.add( new Integer(42) );
•
Collection enthält String- und Integer-Instanzen
– add-Methode akzeptiert nur Object-Instanzen
– Iterator kann daher nur Object zurückgeben
•
Beispielhafte Iteration über diese Collection
– for(Object o : c)
System.out.println(“Länge: “ + ((String)o).length());
•
Problem: Typsicherheit
– Wie stellt man sicher, dass in einer Collection nur Daten eines bestimmten Typs
gespeichert werden können?
#17
Wie speichert man Daten?
• class IntBox
{
private int val;
}
• class StringBox
{
private String val;
void setValue( int val )
{
this.val = val;
}
void setValue( String val )
{
this.val = val;
}
int getValue()
{
return val;
}
String getValue()
{
return val;
}
}
#18
Wie implementiert man „generische“ Typen?
•
•
Häufig durch Speichern von ObjectInstanzen
•
– Box b = new Box();
Point p = new Point(1,2);
class ObjectBox
{
private Object val;
void setValue( Object val )
{
this.val = val;
}
Object getValue()
{
return val;
}
}
Verwendung
b.setValue( p );
((Point)b.getValue()).getX();
•
Probleme
– Umständlich
•
Jeder Zugriff erfordert Typ-Cast
– Unsicher
•
Typ-Cast kann fehlschlagen
• ((Vector)b.getValue()).doX();
 ClassCastException
#19
Lösung: Generische Typen in Java
• Sog. Java Generics
– Klassen und Methoden können „generisch“ implementiert
werden
• Statt Object wird ein Platzhalter-Typ verwendet
– Alt: private Object val;
– Neu: private T val;
• Dieser Typ kann wie ein normaler Typ verwendet werden
– Bei der konkreten Verwendung muss T spezifiert werden
#20
Lösung: Java Generics
• class ObjectBox
{
private Object val;
}
• class Box<T>
{
private T val;
Sagt Java, dass T
im Folgenden ein
Platzhalter ist
void setValue( Object val )
{
this.val = val;
}
void setValue(T val)
{
this.val = val;
}
Object getValue()
{
return val;
}
T getValue()
{
return val;
}
}
#21
Verwendung
• Instanziierung
– Box<String> stringBox = new Box<String>();
– Box<Integer> intBox = new Box<Integer>();
– Box<Point> pointBox = new Box<Point>();
• Zugriff
– Point p = new Point(1,2);
pointBox.setValue( p );
double x = pointBox.getValue().getX();
 getValue() liefert Point zurück
#22
Generics: Einfache generische Methoden
•
class HopOderTop
{
public static <T> T aOderB(T a, T b)
{
if (Math.random() > 0.5)
return a;
else
return b;
}
}
• System.out.println(
HopOderTop.aOderB(“Zuhören“, “Weiterschlafen“)
);
• System.out.println(
“Note: “ + HopOderTop.aOderB( 1.0, 1.3 )
);
#23
Seit Java 1.5 verwendet das JCF Generics
• Alt: Collection l
= new ArrayList();
• Neu: Collection<String>
= new ArrayList<String>();
• Vorteile
– Es können keine falschen Datentypen mehr gespeichert werden
– Typ-Cast entfällt
– Beispiele: nächste Folie
#24
Beispiel: Ohne und mit Generics
#25
Herunterladen