11.11.2014 Aufrufe

1. Referenzdatentypen: Felder und Strings

1. Referenzdatentypen: Felder und Strings

1. Referenzdatentypen: Felder und Strings

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!