001: /*
002: * Primitive Collections for Java.
003: * Copyright (C) 2003 Søren Bak
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package bak.pcj.adapter;
020:
021: import bak.pcj.map.ByteKeyMap;
022: import bak.pcj.map.ByteKeyMapIterator;
023: import bak.pcj.hash.DefaultByteHashFunction;
024: import bak.pcj.util.Exceptions;
025:
026: import java.util.Iterator;
027: import java.util.Collection;
028: import java.util.AbstractSet;
029: import java.util.Map;
030: import java.util.Set;
031:
032: /**
033: * This class represents adapters of primitive maps from
034: * byte values to objects to Java Collections
035: * Framework maps. The adapter is implemented as a wrapper
036: * around a primitive map. Thus,
037: * changes to the underlying map are reflected by this
038: * map and vice versa.
039: *
040: * @see ByteKeyMap
041: * @see java.util.Map
042: *
043: * @author Søren Bak
044: * @version 1.1 20-08-2003 23:03
045: * @since 1.0
046: */
047: public class ByteKeyMapToMapAdapter implements Map {
048:
049: /** The underlying primitive map. */
050: protected ByteKeyMap map;
051:
052: /**
053: * Creates a new adaption of a primitive map of byte
054: * keys to a Java Collections Framework map.
055: *
056: * @param map
057: * the underlying primitive map.
058: *
059: * @throws NullPointerException
060: * if <tt>map</tt> is <tt>null</tt>.
061: */
062: public ByteKeyMapToMapAdapter(ByteKeyMap map) {
063: if (map == null)
064: Exceptions.nullArgument("map");
065: this .map = map;
066: }
067:
068: /**
069: * Clears this map. The underlying map is cleared.
070: *
071: * @throws UnsupportedOperationException
072: * if the operation is not supported by the
073: * underlying map.
074: */
075: public void clear() {
076: map.clear();
077: }
078:
079: /**
080: * Indicates whether this map contains a mapping from a specified
081: * key. This is so, only if the underlying collection contains
082: * the unwrapped key.
083: *
084: * @param key
085: * the key to test for.
086: *
087: * @return <tt>true</tt> if this map contains a mapping from
088: * the specified key; returns <tt>false</tt>
089: * otherwise.
090: *
091: * @throws NullPointerException
092: * if <tt>key</tt> is <tt>null</tt>.
093: *
094: * @throws ClassCastException
095: * if <tt>key</tt> is not of class {@link Byte Byte}.
096: */
097: public boolean containsKey(Object key) {
098: return map.containsKey(((Byte) key).byteValue());
099: }
100:
101: /**
102: * Indicates whether this map contains a mapping to a specified
103: * value.
104: *
105: * @param value
106: * the value to test for.
107: *
108: * @return <tt>true</tt> if this map contains at least one
109: * mapping to the specified value; returns
110: * <tt>false</tt> otherwise.
111: */
112: public boolean containsValue(Object value) {
113: return map.containsValue(value);
114: }
115:
116: /**
117: * Returns a set view of the entries of this map. The returned
118: * set is a view, so changes to this map are reflected by the
119: * returned set and vice versa. All elements of the returned
120: * set implements {@link java.util.Map.Entry java.util.Map.Entry}.
121: *
122: * @return a set view of the entries of this map.
123: */
124: public Set entrySet() {
125: return new EntrySet();
126: }
127:
128: /**
129: * Indicates whether this map is equal to some object.
130: *
131: * @param obj
132: * the object with which to compare this map.
133: *
134: * @return <tt>true</tt> if this map is equal to the
135: * specified object; returns <tt>false</tt>
136: * otherwise.
137: */
138: public boolean equals(Object obj) {
139: if (!(obj instanceof Map))
140: return false;
141: Map m = (Map) obj;
142: if (m.size() != map.size())
143: return false;
144: Iterator i = m.entrySet().iterator();
145: while (i.hasNext()) {
146: Map.Entry e = (Map.Entry) i.next();
147: if (e.getKey() == null)
148: return false;
149: if (e.getValue() == null)
150: return false;
151: if (!get(e.getKey()).equals(e.getValue()))
152: return false;
153: }
154: return true;
155: }
156:
157: /**
158: * Maps a specified key to a value. Returns <tt>null</tt>
159: * if no mapping exists for the specified key.
160: *
161: * @param key
162: * the key to map to a value.
163: *
164: * @return the value that the specified key maps to, or
165: * <tt>null</tt>, if no such mapping exists.
166: *
167: * @throws NullPointerException
168: * if <tt>key</tt> is <tt>null</tt>.
169: *
170: * @throws ClassCastException
171: * if <tt>key</tt> is not of class {@link Byte Byte}.
172: */
173: public Object get(Object key) {
174: byte k = ((Byte) key).byteValue();
175: return map.get(k);
176: }
177:
178: /**
179: * Returns a hash code value for this map. The hash code
180: * returned is that of the underlying map.
181: *
182: * @return a hash code value for this map.
183: */
184: public int hashCode() {
185: return map.hashCode();
186: }
187:
188: /**
189: * Indicates whether this map is empty.
190: *
191: * @return <tt>true</tt> if this map is empty; returns
192: * <tt>false</tt> otherwise.
193: */
194: public boolean isEmpty() {
195: return map.isEmpty();
196: }
197:
198: /**
199: * Returns a set view of the keys of this map. Removals from the
200: * returned set removes the corresponding entries in this map.
201: * Changes to the map are reflected in the set. All elements
202: * if the returned set is of class {@link Byte Byte}.
203: *
204: * @return a set view of the keys of this map.
205: */
206: public Set keySet() {
207: return new ByteSetToSetAdapter(map.keySet());
208: }
209:
210: /**
211: * Adds a mapping from a specified key to a specified value to
212: * this map. If a mapping already exists for the specified key
213: * it is overwritten by the new mapping. The mapping is
214: * added to the underlying map.
215: *
216: * @param key
217: * the key of the mapping to add to this map.
218: *
219: * @param value
220: * the value of the mapping to add to this map.
221: *
222: * @return the old value if a
223: * mapping from the specified key already existed
224: * in this map; returns <tt>null</tt> otherwise.
225: *
226: * @throws UnsupportedOperationException
227: * if the operation is not supported by this map.
228: *
229: * @throws NullPointerException
230: * if <tt>key</tt> is <tt>null</tt>;
231: * if <tt>value</tt> is <tt>null</tt>.
232: *
233: * @throws ClassCastException
234: * if <tt>key</tt> is not of class {@link Byte Byte}.
235: */
236: public Object put(Object key, Object value) {
237: byte k = ((Byte) key).byteValue();
238: return map.put(k, value);
239: }
240:
241: /**
242: * Adds all mappings from a specified map to this map. Any
243: * existing mappings whose keys collide with a new mapping is
244: * overwritten by the new mapping. The mappings are
245: * added to the underlying map.
246: *
247: * @param map
248: * the map whose mappings to add to this map.
249: *
250: * @throws NullPointerException
251: * if <tt>map</tt> is <tt>null</tt>.
252: *
253: * @throws UnsupportedOperationException
254: * if the operation is not supported by this map.
255: *
256: * @throws NullPointerException
257: * if a key in <tt>map</tt> is <tt>null</tt>.
258: *
259: * @throws ClassCastException
260: * if a key in <tt>map</tt> is not of class {@link Byte Byte}.
261: */
262: public void putAll(Map map) {
263: Iterator i = map.entrySet().iterator();
264: while (i.hasNext()) {
265: Map.Entry e = (Map.Entry) i.next();
266: put(e.getKey(), e.getValue());
267: }
268: }
269:
270: /**
271: * Removes the mapping from a specified key from this map.
272: * The mapping is removed from the underlying map.
273: *
274: * @param key
275: * the key whose mapping to remove from this map.
276: *
277: * @return the old value if a
278: * mapping from the specified key already existed
279: * in this map; returns <tt>null</tt> otherwise.
280: *
281: * @throws UnsupportedOperationException
282: * if the operation is not supported by the
283: * underlying map.
284: */
285: public Object remove(Object key) {
286: if (key == null)
287: return null;
288: if (!(key instanceof Byte))
289: return null;
290: byte k = ((Byte) key).byteValue();
291: return map.remove(k);
292: }
293:
294: /**
295: * Returns the size of this map. The size is defined as the
296: * number of mappings from keys to values. The size is that
297: * of the underlying map.
298: *
299: * @return the size of this map.
300: */
301: public int size() {
302: return map.size();
303: }
304:
305: /**
306: * Returns a collection view of the values in this map. The
307: * collection is not modifiable, but changes to the map are
308: * reflected in the collection.
309: *
310: * @return a collection view of the values in this map.
311: */
312: public Collection values() {
313: return map.values();
314: }
315:
316: class EntrySet extends AbstractSet {
317:
318: public Iterator iterator() {
319: return new Iterator() {
320: ByteKeyMapIterator i = map.entries();
321:
322: public boolean hasNext() {
323: return i.hasNext();
324: }
325:
326: public Object next() {
327: i.next();
328: return new Entry(i.getKey(), i.getValue());
329: }
330:
331: public void remove() {
332: i.remove();
333: }
334: };
335: }
336:
337: public boolean add(Object obj) {
338: Map.Entry e = (Map.Entry) obj;
339: if (contains(e))
340: return false;
341: put(e.getKey(), e.getValue());
342: return true;
343: }
344:
345: public int size() {
346: return map.size();
347: }
348: }
349:
350: class Entry implements Map.Entry {
351: Byte key;
352: Object value;
353:
354: Entry(byte key, Object value) {
355: this .key = new Byte(key);
356: this .value = value;
357: }
358:
359: public Object getKey() {
360: return key;
361: }
362:
363: public Object getValue() {
364: return value;
365: }
366:
367: public Object setValue(Object value) {
368: return put(key, value);
369: }
370:
371: public int hashCode() {
372: return DefaultByteHashFunction.INSTANCE.hash(key
373: .byteValue())
374: ^ value.hashCode();
375: }
376:
377: public boolean equals(Object obj) {
378: if (!(obj instanceof Map.Entry))
379: return false;
380: Map.Entry e = (Map.Entry) obj;
381: return key.equals(e.getKey()) && value.equals(e.getValue());
382: }
383: }
384:
385: }
|