1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
<html>
<head>
<title>
Handbuch der Java-Programmierung, 5. Auflage
</title>
</head>
<body>
<a name="startofbody"></a>
<script language="JavaScript" src="hjp4lib.js">
</script>
<script language="JavaScript">
installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100097.html;106,k100097.html;107,k100099.html;108,k100107.html");
</script>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100097.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100097.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100099.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100107.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">Kapitel 15 - Collections II
</table>
<hr>
<!-- Section -->
<a name="sectlevel2id015001"></a>
<h2>15.1 Grundlagen und Konzepte </h2>
<hr>
<ul>
<li><a href="k100098.html#sectlevel2id015001">15.1 Grundlagen und Konzepte</a>
</ul>
<hr>
<p>
Wie in <a href="k100090.html#kapitelcollections1">Kapitel 14</a> erläutert,
gibt es seit dem JDK 1.0 die »traditionellen« Collections
mit den Klassen <a href="index_v.html#ixb100120"><font color=#000080><tt>Vector</tt></font></a>,
<a href="index_s.html#ixb100674"><font color=#000080><tt>Stack</tt></font></a>,
<a href="index_d.html#ixb100675"><font color=#000080><tt>Dictionary</tt></font></a>,
<a href="index_h.html#ixb100419"><font color=#000080><tt>Hashtable</tt></font></a>
und <a href="index_b.html#ixb100676"><font color=#000080><tt>BitSet</tt></font></a>.
Obwohl sie ihren Zweck durchaus erfüllen, gab es einige Kritik
am Collections-Konzept des JDK 1.0. Zunächst wurde die geringe
Vielseitigkeit kritisiert, etwa im Vergleich zum mächtigen Collection-Konzept
der Sprache SmallTalk. Zudem galten die JDK-1.0-Collections als nicht
sehr performant. Fast alle wichtigen Methoden sind <a name="ixa100919"><a href="index_s.html#ixb100715"><font color=#000080><tt>synchronized</tt></font></a></a>,
und als generische Speicher von Elementen des Typs <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
ist bei jedem Zugriff ein Typecast bzw. eine Typüberprüfung
notwendig (wir kommen auf diese Begriffe in <a href="k100143.html#kapitelmultithreading">Kapitel 22</a>
zurück). Zudem gab es Detailschwächen, die immer wieder
kritisiert wurden. Als Beispiel kann die Wahl der Methodennamen des
<a href="index_e.html#ixb100122"><font color=#000080><tt>Enumeration</tt></font></a>-Interfaces
genannt werden. Oder die Implementierung der Klasse <a href="index_s.html#ixb100674"><font color=#000080><tt>Stack</tt></font></a>,
die als Ableitung von <a href="index_v.html#ixb100120"><font color=#000080><tt>Vector</tt></font></a>
weit über ihr eigentliches Ziel hinausschießt.
<p>
Diese Kritik wurde von den Java-Designern zum Anlaß genommen,
das Collection-Konzept im Rahmen der Version 1.2 neu zu überdenken.
Herausgekommen ist dabei eine Sammlung von gut 20 Klassen und Interfaces
im Paket <a name="ixa100920"><a href="index_j.html#ixb100127"><font color=#000080><tt>java.util</tt></font></a></a>,
die das Collections-Framework des JDK 1.2 bilden. Wer bei dieser Zahl
erschreckt, sei getröstet. Letztlich werden im wesentlichen die
drei Grundformen <a name="ixa100921"><a href="index_s.html#ixb100716"><font color=#000080><tt>Set</tt></font></a></a>,
<a name="ixa100922"><a href="index_l.html#ixb100717"><font color=#000080><tt>List</tt></font></a></a>
und <a name="ixa100923"><a href="index_m.html#ixb100718"><font color=#000080><tt>Map</tt></font></a></a>
realisiert. Die große Anzahl ergibt sich aus der Bereitstellung
verschiedender Implementierungsvarianten, Interfaces und einiger abstrakter
Basisklassen, mit denen die Implementierung eigener Collections vereinfacht
werden kann. Wir wollen uns zunächst mit der grundlegenden Arbeitsweise
der Collection-Typen vertraut machen:
<ul>
<li>Eine <a href="index_l.html#ixb100717"><font color=#000080><tt>List</tt></font></a>
ist eine beliebig große Liste von Elementen beliebigen Typs,
auf die sowohl wahlfrei als auch sequenziell zugegriffen werden kann.
<li>Ein <a href="index_s.html#ixb100716"><font color=#000080><tt>Set</tt></font></a>
ist eine (doublettenlose) Menge von Elementen, auf die mit typischen
Mengenoperationen zugegriffen werden kann.
<li>Eine <a href="index_m.html#ixb100718"><font color=#000080><tt>Map</tt></font></a>
ist eine Abbildung von Elementen eines Typs auf Elemente eines anderen
Typs, also eine Menge zusammengehöriger Paare von Objekten.
</ul>
<p>
Jede dieser Grundformen ist als Interface unter dem oben angegebenen
Namen implementiert. Zudem gibt es jeweils eine oder mehrere konkrete
Implementierungen. Sie unterscheiden sich in den verwendeten Datenstrukturen
und Algorithmen und damit in ihrer Eignung für verschiedene Anwendungsfälle.
Weiterhin gibt es eine abstrakte Implementierung des Interfaces, mit
dessen Hilfe das Erstellen eigener Collections erleichtert wird.
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100%>
<tr>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=1></td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top width=1000>
<p>
Im Gegensatz zu den 1.1-Klassen sind die Collections des JDK 1.2 aus
Performancegründen durchgängig unsynchronisiert. Soll also
von mehr als einem Thread gleichzeitig auf eine Collection zugegriffen
werden (Collections sind häufig Kommunikationsmittel zwischen
gekoppelten Threads), so ist unbedingt darauf zu achten, die Zugriffe
selbst zu synchronisieren. Andernfalls können leicht Programmfehler
und Dateninkonsistenzen entstehen. Wie Sie den Zugriff auf die Klassen
des Collection Frameworks synchronisieren erfahren Sie in <a href="k100104.html#subsectionsynccollections">Abschnitt 15.7.2</a>.</td>
<td><img src="trp1_1.gif" width=2></td>
<td valign=top>
<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#FF9900">
<tr>
<td><font color="#FFFFFF"> JDK1.1-6.0 </font></td>
</tr>
</table>
</td>
<td width=1 align=left valign=top bgcolor="#FF9900"><img src="trp1_1.gif"></td>
</tr>
</table>
<p>
Die Namensgebung der Interfaces und Klassen folgt einem einfachen
Schema. Das Interface hat immer den allgemein verwendeten Namen der
zu implementierenden Collection, also beispielsweise <a href="index_l.html#ixb100717"><font color=#000080><tt>List</tt></font></a>,
<a href="index_s.html#ixb100716"><font color=#000080><tt>Set</tt></font></a>
oder <a href="index_m.html#ixb100718"><font color=#000080><tt>Map</tt></font></a>.
Jede Implementierungsvariante stellt vor den Namen dann eine spezifische
Bezeichnung, die einen Hinweis auf die Art der verwendeten Datenstrukturen
und Algorithmen geben soll. So gibt es für das Interface <a href="index_l.html#ixb100717"><font color=#000080><tt>List</tt></font></a>
beispielsweise die Implementierungsvarianten <a name="ixa100924"><a href="index_l.html#ixb100695"><font color=#000080><tt>LinkedList</tt></font></a></a>
und <a name="ixa100925"><a href="index_a.html#ixb100719"><font color=#000080><tt>ArrayList</tt></font></a></a>
sowie die abstrakte Implementierung <a name="ixa100926"><a href="index_a.html#ixb100720"><font color=#000080><tt>AbstractList</tt></font></a></a>.
Wenn man dieses Schema einmal begriffen hat, verliert der »Collection-Zoo«
viel von seinem Schrecken.
<p>
Die Interfaces spielen eine wichtige Rolle, denn sie beschreiben bereits
recht detailliert die Eigenschaften der folgenden Implementierungen.
Dabei wurde im JDK 1.2 eine weitreichende Design-Entscheidung getroffen.
Um nicht für jede denkbare Collection-Klasse ein eigenes Interface
definieren zu müssen, wurde ein Basisinterface <a name="ixa100927"><a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a></a>
geschaffen, aus dem die meisten Interfaces abgeleitet wurden. Es fasst
die wesentlichen Eigenschaften einer großen Menge unterschiedlicher
Collections zusammen:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
int size()
boolean isEmpty()
boolean contains(Object o)
Iterator iterator()
Object[] toArray()
Object[] toArray(Object[] a)
boolean add(Object o)
boolean remove(Object o)
boolean containsAll(Collection c)
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean retainAll(Collection c)
void clear()
boolean equals(Object o)
int hashCode()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/util/Collection.html" onClick="this.href=getApiDoc('java.util.Collection')"><font color="#660066" size=-1>java.util.Collection</font></a></td>
</tr>
</table>
<p>
Zusätzlich fordert die JDK-1.2-Spezifikation für jede Collection-Klasse
zwei Konstruktoren (was ja leider nicht im Rahmen der Interface-Definition
sichergestellt werden kann). Ein parameterloser Konstruktor wird verwendet,
um eine leere Collection anzulegen. Ein weiterer, der ein einzelnes
<a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>-Argument
besitzt, dient dazu, eine neue Collection anzulegen und mit allen
Elementen aus der als Argument übergebenen Collection zu füllen.
Die Interfaces <a href="index_l.html#ixb100717"><font color=#000080><tt>List</tt></font></a>
und <a href="index_s.html#ixb100716"><font color=#000080><tt>Set</tt></font></a>
sind direkt aus <a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>
abgeleitet, <a name="ixa100928"><a href="index_s.html#ixb100722"><font color=#000080><tt>SortedSet</tt></font></a></a>
entstammt ihr (als Nachfolger von <a href="index_s.html#ixb100716"><font color=#000080><tt>Set</tt></font></a>)
mittelbar. Lediglich die Interfaces <a href="index_m.html#ixb100718"><font color=#000080><tt>Map</tt></font></a>
und das daraus abgeleitete Interface <a name="ixa100929"><a href="index_s.html#ixb100723"><font color=#000080><tt>SortedMap</tt></font></a></a>
wurden nicht aus <a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>
abgeleitet.
<p>
Der Vorteil dieses Designs ist natürlich, dass eine flexible
Schnittstelle für den Umgang mit <i>Mengen von Objekten</i> zur
Verfügung steht. Wenn eine Methode einen Rückgabewert vom
Typ <a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>
besitzt, können die Aufrufer dieser Methode auf die zurückgegebenen
Elemente - unabhängig vom Typ der tatsächlich zurückgegebenen
Collection-Klasse - einheitlich zugreifen. Selbst wenn eine andere
<i>Implementierung</i> gewählt wird, ändert sich für
den Aufrufer nichts, solange das zurückgegebene Objekt das <a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>-Interface
implementiert.
<p>
Soweit zur Theorie. Der designerische Nachteil dieses Ansatzes besteht
darin, dass längst nicht alle tatsächlichen Collections
eine Schnittstelle besitzen, wie sie in <a href="index_c.html#ixb100721"><font color=#000080><tt>Collection</tt></font></a>
definiert wurde. Während diese für eine Liste noch passen
mag, besitzt eine Queue oder ein Stack gänzlich anders arbeitende
Zugriffsroutinen. Dieser Konflikt wurde dadurch zu lösen versucht,
dass die Methoden <i>zum Ändern</i> der Collection <i>optional</i>
sind. Während also <a name="ixa100930"><a href="index_c.html#ixb100700"><font color=#000080><tt>contains</tt></font></a></a>,
<a name="ixa100931"><a href="index_c.html#ixb100724"><font color=#000080><tt>containsAll</tt></font></a></a>,
<a href="index_e.html#ixb100223"><font color=#000080><tt>equals</tt></font></a>,
<a name="ixa100932"><a href="index_h.html#ixb100418"><font color=#000080><tt>hashCode</tt></font></a></a>,
<a name="ixa100933"><a href="index_i.html#ixb100678"><font color=#000080><tt>isEmpty</tt></font></a></a>,
<a name="ixa100934"><a href="index_s.html#ixb100679"><font color=#000080><tt>size</tt></font></a></a>
und <a name="ixa100935"><a href="index_t.html#ixb100725"><font color=#000080><tt>toArray</tt></font></a></a>
obligatorisch sind, müssen die übrigen Methoden in einer
konkreten Implementierung nicht unbedingt zur Verfügung gestellt
werden, sondern können weggelassen, ersetzt oder ergänzt
werden.
<p>
Aus <a href="k100057.html#kapiteloop3">Kapitel 9</a> wissen wir allerdings,
dass <i>alle</i> definierten Methoden eines Interfaces in einer konkreten
Implementierung zur Verfügung gestellt werden müssen. Davon
sind natürlich auch die Collection-Klassen nicht ausgenommen.
Wenn sich diese entschließen, eine optionale Methode nicht zu
realisieren, so muss diese zwar implementiert werden, löst aber
beim Aufruf eine Exception des Typs <a name="ixa100936"><a href="index_u.html#ixb100726"><font color=#000080><tt>UnsupportedOperationException</tt></font></a></a>
aus. Die tatsächliche Schnittstelle einer konkreten Collection-Klasse
kann also nicht dem Interface entnommen werden, das sie implementiert,
sondern erfordert zusätzlich die schriftliche Dokumentation der
Klasse.
<p>
Über diesen Designansatz kann man sich streiten. Da sowieso nur
die nicht-verändernden Methoden nicht-optional sind, hätte
man ebenso gut diese allein in ein generisches Collection-Interface
stecken können und von allen Collection-Klassen implementieren
lassen können. Zusätzliche Methoden wären dann in abgeleiteten
Interfaces passend zur jeweiligen Collection-Klasse zu definieren.
<hr>
<table border=0 cellpadding=0 cellspacing=1 width="100%">
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
Wesley, Version 5.0.1
<tr bgcolor="#EEFFCC">
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100097.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100097.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100099.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100107.html"> >> </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
<td align="right">© 1998, 2007 Guido Krüger & Thomas
Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
</table>
<a name="endofbody"></a>
</body>
</html>
|