001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb.lib;
032:
033: /**
034: * Implementation of an Map which maintains the user-defined order of the keys.
035: * Key/value pairs can be accessed by index or by key. Iterators return the
036: * keys or values in the index order.
037: *
038: * This class does not store null keys.
039: *
040: * @author fredt@users
041: * @version 1.7.2
042: * @since 1.7.2
043: */
044: public class HashMappedList extends HashMap {
045:
046: public HashMappedList() {
047: this (16, 0.75f);
048: }
049:
050: public HashMappedList(int initialCapacity)
051: throws IllegalArgumentException {
052: this (initialCapacity, 0.75f);
053: }
054:
055: public HashMappedList(int initialCapacity, float loadFactor)
056: throws IllegalArgumentException {
057: super (initialCapacity, loadFactor);
058: }
059:
060: public Object get(int index) throws IndexOutOfBoundsException {
061:
062: checkRange(index);
063:
064: return objectValueTable[index];
065: }
066:
067: public Object remove(Object key) {
068:
069: int lookup = getLookup(key, key.hashCode());
070:
071: if (lookup < 0) {
072: return null;
073: }
074:
075: Object returnValue = super .remove(key);
076:
077: removeRow(lookup);
078:
079: return returnValue;
080: }
081:
082: public Object remove(int index) throws IndexOutOfBoundsException {
083:
084: checkRange(index);
085:
086: return remove(objectKeyTable[index]);
087: }
088:
089: public boolean add(Object key, Object value) {
090:
091: if (keySet().contains(key)) {
092: return false;
093: }
094:
095: super .put(key, value);
096:
097: return true;
098: }
099:
100: public Object put(Object key, Object value) {
101: return super .put(key, value);
102: }
103:
104: public Object set(int index, Object value)
105: throws IndexOutOfBoundsException {
106:
107: checkRange(index);
108:
109: Object returnValue = objectKeyTable[index];
110:
111: objectKeyTable[index] = value;
112:
113: return returnValue;
114: }
115:
116: public boolean insert(int index, Object key, Object value)
117: throws IndexOutOfBoundsException {
118:
119: if (index < 0 || index > size()) {
120: throw new IndexOutOfBoundsException();
121: }
122:
123: if (keySet().contains(key)) {
124: return false;
125: }
126:
127: if (index == size()) {
128: return add(key, value);
129: }
130:
131: HashMappedList hm = new HashMappedList(size());
132:
133: for (int i = index; i < size(); i++) {
134: hm.add(getKey(i), get(i));
135: }
136:
137: for (int i = size() - 1; i >= index; i--) {
138: remove(i);
139: }
140:
141: for (int i = 0; i < hm.size(); i++) {
142: add(hm.getKey(i), hm.get(i));
143: }
144:
145: return true;
146: }
147:
148: public boolean set(int index, Object key, Object value)
149: throws IndexOutOfBoundsException {
150:
151: checkRange(index);
152:
153: if (keySet().contains(key) && getIndex(key) != index) {
154: return false;
155: }
156:
157: super .remove(objectKeyTable[index]);
158: super .put(key, value);
159:
160: return true;
161: }
162:
163: public boolean setKey(int index, Object key)
164: throws IndexOutOfBoundsException {
165:
166: checkRange(index);
167:
168: Object value = objectValueTable[index];
169:
170: return set(index, key, value);
171: }
172:
173: public Object getKey(int index) throws IndexOutOfBoundsException {
174:
175: checkRange(index);
176:
177: return objectKeyTable[index];
178: }
179:
180: public int getIndex(Object key) {
181: return getLookup(key, key.hashCode());
182: }
183:
184: private void checkRange(int i) {
185:
186: if (i < 0 || i >= size()) {
187: throw new IndexOutOfBoundsException();
188: }
189: }
190: }
|