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 com.uwyn.rife.pcj.map;
020:
021: import com.uwyn.rife.pcj.hash.DefaultCharHashFunction;
022:
023: /**
024: * This class represents an abstract base for implementing
025: * maps from char values to objects. All operations that can be implemented
026: * using iterators
027: * are implemented as such. In most cases, this is
028: * hardly an efficient solution, and at least some of those
029: * methods should be overridden by sub-classes.
030: *
031: * @author Søren Bak
032: * @version 1.0 2003/10/1
033: * @since 1.0
034: */
035: public abstract class AbstractCharKeyMap<E> implements CharKeyMap<E> {
036:
037: /** Default constructor to be invoked by sub-classes. */
038: protected AbstractCharKeyMap() {
039: }
040:
041: public void clear() {
042: CharKeyMapIterator i = entries();
043: while (i.hasNext()) {
044: i.next();
045: i.remove();
046: }
047: }
048:
049: public E remove(char key) {
050: CharKeyMapIterator<E> i = entries();
051: while (i.hasNext()) {
052: i.next();
053: if (i.getKey() == key) {
054: E value = i.getValue();
055: i.remove();
056: return value;
057: }
058: }
059: return null;
060: }
061:
062: public void putAll(CharKeyMap<E> map) {
063: CharKeyMapIterator<E> i = map.entries();
064: while (i.hasNext()) {
065: i.next();
066: put(i.getKey(), i.getValue());
067: }
068: }
069:
070: public boolean containsKey(char key) {
071: CharKeyMapIterator i = entries();
072: while (i.hasNext()) {
073: i.next();
074: if (i.getKey() == key)
075: return true;
076: }
077: return false;
078: }
079:
080: public E get(char key) {
081: CharKeyMapIterator<E> i = entries();
082: while (i.hasNext()) {
083: i.next();
084: if (i.getKey() == key)
085: return i.getValue();
086: }
087: return null;
088: }
089:
090: public boolean containsValue(Object value) {
091: CharKeyMapIterator i = entries();
092: if (value == null) {
093: while (i.hasNext()) {
094: i.next();
095: if (value == null)
096: return true;
097: }
098: } else {
099: while (i.hasNext()) {
100: i.next();
101: if (value.equals(i.getValue()))
102: return true;
103: }
104: }
105: return false;
106: }
107:
108: public boolean equals(Object obj) {
109: if (!(obj instanceof CharKeyMap))
110: return false;
111: CharKeyMap map = (CharKeyMap) obj;
112: if (size() != map.size())
113: return false;
114: CharKeyMapIterator<E> i = entries();
115: while (i.hasNext()) {
116: i.next();
117: char k = i.getKey();
118: E v = i.getValue();
119: if (v == null) {
120: if (map.get(k) != null)
121: return false;
122: if (!map.containsKey(k))
123: return false;
124: } else {
125: if (!v.equals(map.get(k)))
126: return false;
127: }
128: }
129: return true;
130: }
131:
132: public int hashCode() {
133: int h = 0;
134: CharKeyMapIterator i = entries();
135: while (i.hasNext()) {
136: i.next();
137: h += (DefaultCharHashFunction.INSTANCE.hash(i.getKey()) ^ i
138: .getValue().hashCode());
139: }
140: return h;
141: }
142:
143: public boolean isEmpty() {
144: return size() == 0;
145: }
146:
147: public int size() {
148: int size = 0;
149: CharKeyMapIterator i = entries();
150: while (i.hasNext()) {
151: i.next();
152: size++;
153: }
154: return size;
155: }
156:
157: /**
158: * Returns a string representation of this map.
159: *
160: * @return a string representation of this map.
161: */
162: public String toString() {
163: StringBuffer s = new StringBuffer();
164: s.append('[');
165: CharKeyMapIterator i = entries();
166: while (i.hasNext()) {
167: if (s.length() > 1)
168: s.append(',');
169: i.next();
170: s.append(String.valueOf(i.getKey()));
171: s.append("->");
172: s.append(String.valueOf(i.getValue()));
173: }
174: s.append(']');
175: return s.toString();
176: }
177:
178: /**
179: * Does nothing. Sub-classes may provide an implementation to
180: * minimize memory usage, but this is not required since many
181: * implementations will always have minimal memory usage.
182: */
183: public void trimToSize() {
184: }
185:
186: }
|