KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > util > NullKeyMap


1 /* ====================================================================
2  * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.util;
54
55 import java.util.*;
56 import java.io.Serializable JavaDoc;
57
58 /******************************************************************************
59  * A Map supporting null keys that wraps a Map that doesn't support null keys.
60  * NullKeyMap substitutes null keys with a special placeholder object. This
61  * technique does not work when the wrapped Map is a TreeMap because it cannot
62  * be compared against other objects. In order for TreeMaps to support null
63  * keys, use any of the null ordering comparators found in the {@link Utils}
64  * class.
65  *
66  * @author Brian S O'Neill
67  * @version
68  * <!--$$Revision:--> 9 <!-- $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
69  */

70 public class NullKeyMap extends AbstractMap implements Serializable JavaDoc {
71     // Instead of using null as a key, use this placeholder.
72
private static final Object JavaDoc NULL = new Serializable JavaDoc() {};
73
74     private Map mMap;
75
76     private transient Set mKeySet;
77     private transient Set mEntrySet;
78
79     /**
80      * @param map The map to wrap.
81      */

82     public NullKeyMap(Map map) {
83         mMap = map;
84     }
85     
86     public int size() {
87         return mMap.size();
88     }
89
90     public boolean isEmpty() {
91         return mMap.isEmpty();
92     }
93
94     public boolean containsKey(Object JavaDoc key) {
95         return (key == null) ? mMap.containsKey(NULL) : mMap.containsKey(key);
96     }
97
98     public boolean containsValue(Object JavaDoc value) {
99         return mMap.containsValue(value);
100     }
101
102     public Object JavaDoc get(Object JavaDoc key) {
103         return (key == null) ? mMap.get(NULL) : mMap.get(key);
104     }
105
106     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
107         return mMap.put((key == null) ? NULL : key, value);
108     }
109
110     public Object JavaDoc remove(Object JavaDoc key) {
111         return (key == null) ? mMap.remove(NULL) : mMap.remove(key);
112     }
113
114     public void putAll(Map map) {
115         Iterator it = map.entrySet().iterator();
116         while (it.hasNext()) {
117             Map.Entry entry = (Map.Entry)it.next();
118             put(entry.getKey(), entry.getValue());
119         }
120     }
121
122     public void clear() {
123         mMap.clear();
124     }
125
126     public Set keySet() {
127         if (mKeySet == null) {
128             mKeySet = new AbstractSet() {
129                 public Iterator iterator() {
130                     final Iterator it = mMap.keySet().iterator();
131
132                     return new Iterator() {
133                         public boolean hasNext() {
134                             return it.hasNext();
135                         }
136
137                         public Object JavaDoc next() {
138                             Object JavaDoc key = it.next();
139                             return (key == NULL) ? null : key;
140                         }
141
142                         public void remove() {
143                             it.remove();
144                         }
145                     };
146                 }
147                 
148                 public boolean contains(Object JavaDoc key) {
149                     return containsKey((key == null) ? NULL : key);
150                 }
151
152                 public boolean remove(Object JavaDoc key) {
153                     if (key == null) {
154                         key = NULL;
155                     }
156                     if (containsKey(key)) {
157                         NullKeyMap.this.remove(key);
158                         return true;
159                     }
160                     else {
161                         return false;
162                     }
163                 }
164
165                 public int size() {
166                     return NullKeyMap.this.size();
167                 }
168                 
169                 public void clear() {
170                     NullKeyMap.this.clear();
171                 }
172             };
173         }
174
175         return mKeySet;
176     }
177
178     public Collection values() {
179         return mMap.values();
180     }
181
182     public Set entrySet() {
183         if (mEntrySet == null) {
184             mEntrySet = new AbstractSet() {
185                 public Iterator iterator() {
186                     final Iterator it = mMap.entrySet().iterator();
187
188                     return new Iterator() {
189                         public boolean hasNext() {
190                             return it.hasNext();
191                         }
192
193                         public Object JavaDoc next() {
194                             final Map.Entry entry = (Map.Entry)it.next();
195                             if (entry.getKey() == NULL) {
196                                 return new AbstractMapEntry() {
197                                     public Object JavaDoc getKey() {
198                                         return null;
199                                     }
200
201                                     public Object JavaDoc getValue() {
202                                         return entry.getValue();
203                                     }
204
205                                     public Object JavaDoc setValue(Object JavaDoc value) {
206                                         return entry.setValue(value);
207                                     }
208                                 };
209                             }
210                             else {
211                                 return entry;
212                             }
213                         }
214
215                         public void remove() {
216                             it.remove();
217                         }
218                     };
219                 }
220                 
221                 public boolean contains(Object JavaDoc obj) {
222                     if (!(obj instanceof Map.Entry)) {
223                         return false;
224                     }
225                     Map.Entry entry = (Map.Entry)obj;
226                     Object JavaDoc key = entry.getKey();
227                     Object JavaDoc value = entry.getValue();
228                     if (key == null) {
229                         key = NULL;
230                     }
231                     Object JavaDoc lookup = get(key);
232                     if (lookup == null) {
233                         return value == null;
234                     }
235                     else {
236                         return lookup.equals(value);
237                     }
238                 }
239
240                 public boolean remove(Object JavaDoc obj) {
241                     if (!(obj instanceof Map.Entry)) {
242                         return false;
243                     }
244                     Map.Entry entry = ((Map.Entry)obj);
245                     Object JavaDoc key = entry.getKey();
246                     if (key == null) {
247                         key = NULL;
248                     }
249                     if (containsKey(key)) {
250                         NullKeyMap.this.remove(key);
251                         return true;
252                     }
253                     else {
254                         return false;
255                     }
256                 }
257
258                 public int size() {
259                     return NullKeyMap.this.size();
260                 }
261                 
262                 public void clear() {
263                     NullKeyMap.this.clear();
264                 }
265             };
266         }
267
268         return mEntrySet;
269     }
270 }
271
Popular Tags