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