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