1. Referenzdatentypen: Felder und Strings
1. Referenzdatentypen: Felder und Strings
1. Referenzdatentypen: Felder und Strings
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eigenschaften von <strong>Referenzdatentypen</strong><br />
<strong>1.</strong> <strong>Referenzdatentypen</strong>: <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong><br />
• <strong>Referenzdatentypen</strong> sind Konstrukte, mit deren Hilfe wir aus einfachen Datentypen<br />
neue “eigene” Typen erzeugen können.<br />
• In Java gibt es prinzipiell zwei Arten von <strong>Referenzdatentypen</strong>: <strong>Felder</strong> <strong>und</strong> Klassen.<br />
• In diesem Kapitel lernen wir den Umgang mit <strong>Felder</strong>n <strong>und</strong> die Benutzung der Klassen<br />
String <strong>und</strong> StringBuffer.<br />
• Die Nutzung von Klassen ist Thema des nächsten Kapitels.<br />
• Die Definition eigener Klassen ist Thema des übernächsten Kapitels.<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 10
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eigenschaften von <strong>Referenzdatentypen</strong><br />
Referenz- vs. einfache Datentypen<br />
• einfacher Datentyp: Eine Speicherzelle, die mit einer Variablen assoziiert ist,<br />
enthält den Wert der Variablen (direkter Zugriff).<br />
• Referenztyp: Eine Speicherzelle, die mit einer Variablen assoziiert ist, enthält eine<br />
Referenz (Verweis, Zeiger) auf eine andere Speicherzelle, die den Wert enthält<br />
(indirekter Zugriff).<br />
symbolische Adresse<br />
b<br />
r<br />
Adresse im Speicher<br />
Inhalt<br />
...<br />
96<br />
...<br />
104<br />
...<br />
124<br />
...<br />
... 4711 ... 124 ... ...<br />
Typ<br />
int<br />
Referenz<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 11
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eigenschaften von <strong>Referenzdatentypen</strong><br />
• Im Unterschied zum einfachen Datentyp wird der Wert 124 der Variablen r nicht als<br />
numerischer Wert interpretiert, sondern als Adresse für eine andere Speicherzelle.<br />
Dort findet sich der “eigentliche” Wert bzw. unser “eigentliches” Objekt.<br />
• Mit der Literalkonstanten null repräsentieren wir eine Referenz, die auf nichts (in<br />
das Nirgendwo) verweist.<br />
Wenn die Variable r von einem Referenztyp ist, dann sind<br />
r = null;<br />
...<br />
if ( r == null )<br />
...<br />
gültige Anweisungen.<br />
• Grafische Notation für Variablen:<br />
b<br />
4711 r<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 12
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Einfache Datentypen<br />
Rückblick: Einfache Datentypen (1)<br />
• Ganzzahlige Datentypen<br />
long int short byte<br />
Repräsentation: Zweierkomplement<br />
• Gleitkommatypen<br />
double float<br />
Repräsentation: 32 bzw. 64 Bit im IEEE 754 Standard<br />
• char<br />
Repräsentation: als vorzeichenloser 16-Bit Integerwert<br />
• boolean<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 13
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Einfache Datentypen<br />
Rückblick: Einfache Datentypen (2)<br />
Zu einem einfachen Datentyp gehört<br />
• sein Wertebereich,<br />
• sein lexikalischer Bereich (Literale) <strong>und</strong><br />
• die zur Verfügung stehenden Operationen.<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 14
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Einfache Datentypen<br />
Einfache Datentypen: Implizite <strong>und</strong> explizite Typumwandlung<br />
• Wir wollen die Addition<br />
92233720366854775000L + 807<br />
durchführen. Der Plus-Operator ist aber nur für Werte des gleichen Typs definiert.<br />
Was tun?<br />
• Der Java-Compiler erkennt, daß der Datentyp zur linken Zahl einen Wertebereich<br />
hat, der den der rechten Zahl umfasst. So wird die 807 vom Compiler in eine<br />
automatisch long-Zahl umgewandelt.<br />
☞ implizite Typkonvertierung (implicite typecast)<br />
• Implizite Typkonvertierungen treten immer dann auf, wenn ein kleinerer Zahlenbereich<br />
in einen größeren Zahlenbereich abgebildet wird.<br />
byte → short → int → long<br />
char → int<br />
float → double<br />
• Ganzzahlige Datentypen können auch implizit in Gleitkommatypen umgewandelt<br />
werden, obwohl dabei R<strong>und</strong>ungsfehler auftreten können.<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 15
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Einfache Datentypen<br />
• Die folgende Anweisung dagegen liefert einen Fehler beim Compilieren:<br />
int i = 3.0;<br />
Gr<strong>und</strong>: 3.0 ist eine double-Zahl. Bei einer Umwandlung nach int geht eventuell<br />
Information verloren.<br />
• Stattdessen könnten wir eine explizite Typkonvertierung (explicite Typecast)<br />
durchführen. Hierzu schreibt man den Zieldatentyp in Klammern vor die entsprechende<br />
Zahl oder Ausdruck.<br />
(int) 3.14<br />
Hier würde der Compiler die Nachkommastellen abschneiden.<br />
• Eine Umwandlung von boolean in einen anderen Datentyp ist nicht möglich.<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 16
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
<strong>Felder</strong><br />
• <strong>Felder</strong> (Arrays) gestatten es, mehrere Variablen durch einen gemeinsamen Namen<br />
anzusprechen <strong>und</strong> lediglich durch einen Index zu unterscheiden.<br />
• Alle diese indizierten Variablen haben dabei den gleichen Typ (Komponententyp,<br />
Basistyp).<br />
• Die Variablen selbst werden als Komponenten des Feldes bezeichnet.<br />
• Der Index zum Ansprechen der Komponenten ist vom Typ int. Hierbei sind nur<br />
nichtnegative Werte erlaubt.<br />
• Wir können uns vorstellen, daß die Komponenten eines Feldes aufeinanderfolgend<br />
im Speicher des Rechners abgelegt sind.<br />
• Der Index für eine Komponente ergibt sich dabei aus der Position innerhalb des<br />
Feldes, von Null aufwärts gezählt.<br />
• Beispiel:<br />
– Repräsentation eines Vektors des IR n : Feld mit double als Komponententyp<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 17
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Deklaration von <strong>Felder</strong>n<br />
Syntax:<br />
Komponententyp[] Variablenname;<br />
Beispiele:<br />
int[] zahlenfolge;<br />
double[] vektor;<br />
• Die eckigen Klammern machen deutlich, daß die Variable ein Feld referenziert, mit<br />
dem Typ links von [] als Komponententyp.<br />
• Als Komponententyp sind nicht nur einfache Datentypen, sondern auch Referenztypen<br />
erlaubt.<br />
String[] wortliste;<br />
• Insbesondere sind auch Feldtypen als Komponententyp erlaubt (hierzu später<br />
mehr).<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 18
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Erzeugung von <strong>Felder</strong>n<br />
☞ Die Deklaration einer Feld-Variablen erzeugt kein Feld!<br />
• Nach der Deklaration existiert eine Variable, die eine Referenz auf ein Feld als<br />
Wert aufnehmen, kann.<br />
• Das eigentliche Feld existiert aber noch nicht.<br />
Syntax zur Erzeugung von <strong>Felder</strong>n:<br />
Variablenname = new Komponententyp [ Feldlänge ];<br />
Beispiele:<br />
zahlenfolge = new int[20];<br />
vektor = new double[3];<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 19
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Deklaration <strong>und</strong> Erzeugung können auch zusammen erfolgen. Beispiele:<br />
int[] zahlenfolge = new int[20];<br />
double[] vektor = new double[3];<br />
Bitte beachten Sie:<br />
☞ Die Größe eines Feldes ist nicht Bestandteil des Typs. Sie wird erst bei der Erzeugung<br />
des Feldes festgelegt.<br />
☞ Die Feldlänge kann durch einen Ausdruck angegeben werden.<br />
☞ Einer Feld-Variable können jederzeit andere <strong>Felder</strong> gleichen Typs zugewiesen werden.<br />
double[] vektor = new double[3];<br />
double[] vektor2 = new double[7];<br />
vektor = new double[3];<br />
vektor = new double[5];<br />
vektor = vektor2;<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 20
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Komponentenzugriff <strong>und</strong> -initialisierung<br />
double[] vektor = new double[3];<br />
Welchen Wert haben die Feldkomponenten nach der Erzeugung?<br />
Dies ist für jeden möglichen Komponententyp festgelegt:<br />
• ganzzahlige Typen: 0<br />
• char: ’\0’<br />
• double bzw. float: 0.0 bzw. 0.0f<br />
• boolean: false<br />
• Referenztyp: null<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 21
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Syntax für die Wertzuweisung an eine Komponente:<br />
Variablenname[Index] = Wert;<br />
Beispiel:<br />
vektor[0] = <strong>1.</strong>0; vektor[1] = 2.0; vektor[2] = -<strong>1.</strong>0;<br />
• Index muß ein Ausdruck sein, der einen int-Wert liefert.<br />
• Der Wert für Index muß zwischen 0 <strong>und</strong> Feldlänge-1 liegen.<br />
• Wert kann natürlich ein beliebiger Ausdruck passend zum Komponententyp sein.<br />
int[] quadratFolge = new int[100];<br />
for (int i=0 ; i
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Syntax für den Zugriff auf den Wert einer Komponente (als Ausdruck):<br />
Variablenname[Index]<br />
Beispiel:<br />
double summe = 0.0;<br />
for (int i=0 ; i
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
• Statt Erzeugung mit new <strong>und</strong> anschließender Initialisierung durch Wertzuweisungen<br />
ist auch eine verkürzte Schreibweise möglich.<br />
• Beispiele:<br />
int[] lottozahlen = { 6, 11, 19, 21, 30, 40 };<br />
double[] vektor = { <strong>1.</strong>0, 2.0, -<strong>1.</strong>0 };<br />
String[] wortliste = { "ganz", "viele", "Wörter" };<br />
• Die geklammerten Ausdrücke heißen Feld-Initialisierer (array initializer).<br />
• Nur Literale oder Konstanten dürfen als Wert in einem Feld-Initialisierer auftreten.<br />
• Diese Schreibweise ist nur in Verbindung mit einer Deklaration erlaubt, nicht für<br />
eine gewöhnliche Zuweisung.<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 24
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Ermittlung der Länge von <strong>Felder</strong>n<br />
• Bei der Erstellung eines Feldes wird dessen Länge in einem zusätzlichem Element<br />
vom Typ int abgespeichert.<br />
• Auf dieses Element kann mit<br />
Variablenname.length<br />
zugegriffen werden.<br />
• Beispiel:<br />
double[] vektor = { <strong>1.</strong>0, 2.0, -<strong>1.</strong>0 };<br />
for (int i=0 ; i
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
Kopieren <strong>und</strong> Vergleichen von Referenzen<br />
double[] v = { <strong>1.</strong>0, 3.0, 5.0, 10.0 };<br />
double[] q = v;<br />
for ( int i=0 ; i
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
• Die Zuweisung q = v; führt zu einer sogenannten Referenzkopie.<br />
• Es wird keine Kopie des Feldes angelegt, sondern q erhält die Referenz, die in v<br />
hinterlegt ist.<br />
• Wirkung: q <strong>und</strong> v verweisen auf das gleiche Feld.<br />
v <strong>1.</strong>0 3.0 5.0 10.0<br />
q<br />
Für die Herstellung einer “echten Kopie” haben wir die folgenden Möglichkeiten:<br />
<strong>1.</strong> Wir benutzen eine Schleife:<br />
double[] v2 = new double[ v.length ];<br />
for ( int i=0 ; i
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
2. Nutzung der Methode System.arraycopy:<br />
System.arraycopy( Quelle, QuelleStartIndex,<br />
Ziel, ZielStartIndex,<br />
Anzahl );<br />
Hierbei ist:<br />
• Quelle: Feld, von dem kopiert werden soll<br />
• QuelleStartIndex: Index, ab der Quelle übertragen werden soll<br />
• Ziel: Feld, in das kopiert werden soll<br />
• ZielStartIndex: Index, ab dem die Eintragungen erfolgen sollen<br />
• Anzahl: Anzahl der zu kopierenden Komponenten<br />
3. Nutzung der vordefinierten Methode clone. Hierzu später mehr.<br />
☞ Alle diese Möglichkeiten legen eine sogenannte flache Kopie an.<br />
☞ D.h. für die Komponenten selbst wird die übliche Zuweisung durchgeführt.<br />
☞ Dies kann problematisch sein, wenn der Komponententyp selbst eine Referenzdatentyp<br />
ist (Referenzkopie).<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 28
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Eindimensionale <strong>Felder</strong><br />
• int[] feld1 = { 1, 2, 3 };<br />
int[] feld2 = { 1, 2, 3 };<br />
• Der Ausdruck feld1 == feld2 liefert false!<br />
• Begründung: Bei <strong>Referenzdatentypen</strong> bedeutet == nicht, daß die Inhalte der referenzierten<br />
<strong>Felder</strong> (oder Objekte) verglichen werden.<br />
• Stattdessen wird geprüft, ob die Referenzen die gleiche Speicherstelle adressieren.<br />
feld1<br />
1 2 3<br />
feld2<br />
1 2 3<br />
• Wie vergleicht man dann die Inhalte von <strong>Felder</strong>n?<br />
☞ Ausprogrammieren<br />
• Achtung: Der Komponententyp kann wieder ein Referenztyp sein!<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 29
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Mehrdimensionale <strong>Felder</strong><br />
Mehrdimensionale <strong>Felder</strong><br />
Mehrdimensionale <strong>Felder</strong> sind vom Prinzip her leicht zu definieren: Der Komponententyp<br />
ist selbst ein Feld.<br />
Beispiele:<br />
double[][] matrix;<br />
int[][] folgeVonFolgen;<br />
String[][] listeVonStringListen;<br />
Sollen alle “inneren” <strong>Felder</strong> die gleiche Länge aufweisen, können wir wiederum den<br />
new-Operator in einfacher Weise verwenden:<br />
matrix = new double[3][4];<br />
folgeVonFolgen = new int[3][50];<br />
listeVonStringListen = new String[5][30];<br />
Peter Becker, Programiersprache Java — FH Bonn-Rhein-Sieg, SS 08 30
<strong>1.</strong> <strong>Felder</strong> <strong>und</strong> <strong>Strings</strong> Mehrdimensionale <strong>Felder</strong><br />
Beispiele für “innere” <strong>und</strong> “äußere” Feldlängen:<br />
• matrix.length liefert 3.<br />
• matrix[0].length liefert 4.<br />
• matrix[2].length liefert ebenfalls 4.<br />
Die “inneren” <strong>Felder</strong> können eine unterschiedliche Länge aufweisen.<br />
int[][] folgeVonFolgen = new int[3][];<br />
for ( int i=0 ; i