GlueGen: src/java/com/jogamp/common/util/ArrayHashMap.java Source File

GlueGen v2.6.0-rc-20250712 GlueGen, Native Binding Generator for Java™ (public API).

ArrayHashMap.java
Go to the documentation of this file.
1/**
2 * Copyright 2015 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29 package com.jogamp.common.util;
30
31import java.util.ArrayList;
32import java.util.Collection;
33import java.util.HashMap;
34import java.util.Iterator;
35import java.util.Map;
36import java.util.Set;
37
38/**
39 * {@link HashMap} implementation backed by an {@link ArrayList} to preserve order of values.
40 *
41 * Implementation properties are:
42 * <ul>
43 * <li> Unique elements utilizing {@link java.lang.Object#hashCode()} for O(1) operations, see below.</li>
44 * <li> Java 1.5 compatible</li>
45 * </ul>
46 *
47 * O(1) operations:
48 * <ul>
49 * <li> put new key-value-pair(s) </li>
50 * <li> test for containment </li>
51 * <li> trying to remove non existent elements </li>
52 * </ul>
53 *
54 * O(n) operations:
55 * <ul>
56 * <li> put existing key-value-pair(s) </li>
57 * <li> removing existing elements</li>
58 * </ul>
59 *
60 * For thread safety, the application shall decorate access to instances via
61 * {@link com.jogamp.common.util.locks.RecursiveLock}.
62 *
63*/
64 public class ArrayHashMap<K, V>
65 implements Cloneable, Map<K, V>
66{
67 /**
68 * Default load factor: {@value}
69 */
70 public static final float DEFAULT_LOAD_FACTOR = 0.75f;
71 /**
72 * The default initial capacity: {@value}
73 */
74 public static final int DEFAULT_INITIAL_CAPACITY = 16;
75
76 private final HashMap<K,V> map; // key -> object
77 private final ArrayList<V> data; // list of objects
78 private final boolean supportNullValue;
79
80 /**
81 *
82 * @param supportNullValue Use {@code true} for default behavior, i.e. {@code null} can be a valid value.
83 * Use {@code false} if {@code null} is not a valid value,
84 * here {@link #put(Object, Object)} and {@link #remove(Object)} will be optimized.
85 * @param initialCapacity use {@link #DEFAULT_INITIAL_CAPACITY} for default
86 * @param loadFactor use {@link #DEFAULT_LOAD_FACTOR} for default
87 * @see #supportsNullValue()
88 */
89 public ArrayHashMap(final boolean supportNullValue, final int initialCapacity, final float loadFactor) {
90 this.map = new HashMap<K,V>(initialCapacity, loadFactor);
91 this.data = new ArrayList<V>(initialCapacity);
92 this.supportNullValue = supportNullValue;
93 }
94
95 /**
96 * @return a shallow copy of this ArrayHashMap, elements are not copied.
97 */
98 public ArrayHashMap(final ArrayHashMap<K, V> o) {
99 map = new HashMap<K, V>(o.map);
100 data = new ArrayList<V>(o.data);
101 supportNullValue = o.supportNullValue;
102 }
103
104 /**
105 * Returns {@code true} for default behavior, i.e. {@code null} can be a valid value.
106 * <p>
107 * Returns {@code false} if {@code null} is not a valid value,
108 * here {@link #put(Object, Object)} and {@link #remove(Object)} are optimized operations.
109 * </p>
110 * @see #ArrayHashMap(boolean, int, float)
111 */
112 public final boolean supportsNullValue() { return supportNullValue; }
113
114 //
115 // Cloneable
116 //
117
118 /**
119 * Implementation uses {@link #ArrayHashMap(ArrayHashMap)}.
120 * @return a shallow copy of this ArrayHashMap, elements are not copied.
121 */
122 @Override
123 public final Object clone() {
124 return new ArrayHashMap<K, V>(this);
125 }
126
127 /**
128 * Returns this object ordered ArrayList. Use w/ care, it's not a copy.
129 * @see #toArrayList()
130 */
131 public final ArrayList<V> getData() { return data; }
132
133 /**
134 * @return a shallow copy of this ArrayHashMap's ArrayList, elements are not copied.
135 * @see #getData()
136 */
137 public final ArrayList<V> toArrayList() {
138 return new ArrayList<V>(data);
139 }
140
141 /** Returns this object hash map. Use w/ care, it's not a copy. */
142 public final HashMap<K,V> getMap() { return map; }
143
144 @Override
145 public final String toString() { return data.toString(); }
146
147 //
148 // Map
149 //
150
151 @Override
152 public final void clear() {
153 data.clear();
154 map.clear();
155 }
156
157 @Override
158 public Set<K> keySet() {
159 return map.keySet();
160 }
161
162 /**
163 * {@inheritDoc}
164 * <p>
165 * See {@link #getData()} and {@link #toArrayList()}.
166 * </p>
167 * @see #getData()
168 * @see #toArrayList()
169 */
170 @Override
171 public Collection<V> values() {
172 return map.values();
173 }
174
175 @Override
176 public Set<java.util.Map.Entry<K, V>> entrySet() {
177 return map.entrySet();
178 }
179
180 @Override
181 public final V get(final Object key) {
182 return map.get(key);
183 }
184
185 /**
186 * {@inheritDoc}
187 * <p>
188 * This is an O(1) operation, in case the key does not exist,
189 * otherwise O(n).
190 * </p>
191 * @throws NullPointerException if {@code value} is {@code null} but {@link #supportsNullValue()} == {@code false}
192 */
193 @Override
194 public final V put(final K key, final V value) throws NullPointerException {
195 final V oldValue;
196 if( supportNullValue ) {
197 // slow path
198 final boolean exists = map.containsKey(key);
199 if(!exists) {
200 // !exists
201 if( null != ( oldValue = map.put(key, value) ) ) {
202 // slips a valid null ..
203 throw new InternalError("Already existing, but checked before: "+key+" -> "+oldValue);
204 }
205 } else {
206 // exists
207 oldValue = map.put(key, value);
208 if( !data.remove(oldValue) ) {
209 throw new InternalError("Already existing, but not in list: "+oldValue);
210 }
211 }
212 } else {
213 checkNullValue(value);
214 // fast path
215 if( null != ( oldValue = map.put(key, value) ) ) {
216 // exists
217 if( !data.remove(oldValue) ) {
218 throw new InternalError("Already existing, but not in list: "+oldValue);
219 }
220 }
221 }
222 if(!data.add(value)) {
223 throw new InternalError("Couldn't add value to list: "+value);
224 }
225 return oldValue;
226 }
227
228 @Override
229 public void putAll(final Map<? extends K, ? extends V> m) {
230 for (final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
231 final Map.Entry<? extends K, ? extends V> e = i.next();
232 put(e.getKey(), e.getValue());
233 }
234 }
235
236 /**
237 * {@inheritDoc}
238 * <p>
239 * This is an O(1) operation, in case the key does not exist,
240 * otherwise O(n).
241 * </p>
242 */
243 @Override
244 public final V remove(final Object key) {
245 if( supportNullValue ) {
246 if( map.containsKey(key) ) {
247 // exists
248 final V oldValue = map.remove(key);
249 if ( !data.remove(oldValue) ) {
250 throw new InternalError("Couldn't remove prev mapped pair: "+key+" -> "+oldValue);
251 }
252 return oldValue;
253 }
254 } else {
255 final V oldValue;
256 if ( null != (oldValue = map.remove(key) ) ) {
257 // exists
258 if ( !data.remove(oldValue) ) {
259 throw new InternalError("Couldn't remove prev mapped pair: "+key+" -> "+oldValue);
260 }
261 }
262 return oldValue;
263 }
264 return null;
265 }
266
267 @Override
268 public final boolean containsKey(final Object key) {
269 return map.containsKey(key);
270 }
271
272 @Override
273 public boolean containsValue(final Object value) {
274 return map.containsValue(value);
275 }
276
277 @Override
278 public final boolean equals(final Object arrayHashMap) {
279 if ( !(arrayHashMap instanceof ArrayHashMap) ) {
280 return false;
281 }
282 return map.equals(((ArrayHashMap<?,?>)arrayHashMap).map);
283 }
284
285 @Override
286 public final int hashCode() {
287 return map.hashCode();
288 }
289
290 @Override
291 public final boolean isEmpty() {
292 return data.isEmpty();
293 }
294
295 @Override
296 public final int size() {
297 return data.size();
298 }
299
300 private static final void checkNullValue(final Object value) throws NullPointerException {
301 if( null == value ) {
302 throw new NullPointerException("Null value not supported");
303 }
304 }
305}
com.jogamp.common.util.ArrayHashMap
HashMap implementation backed by an ArrayList to preserve order of values.
Definition: ArrayHashMap.java:66
com.jogamp.common.util.ArrayHashMap.hashCode
final int hashCode()
Definition: ArrayHashMap.java:286
com.jogamp.common.util.ArrayHashMap.clone
final Object clone()
Implementation uses ArrayHashMap(ArrayHashMap).
Definition: ArrayHashMap.java:123
com.jogamp.common.util.ArrayHashMap.containsKey
final boolean containsKey(final Object key)
Definition: ArrayHashMap.java:268
com.jogamp.common.util.ArrayHashMap.supportsNullValue
final boolean supportsNullValue()
Returns true for default behavior, i.e.
Definition: ArrayHashMap.java:112
com.jogamp.common.util.ArrayHashMap.containsValue
boolean containsValue(final Object value)
Definition: ArrayHashMap.java:273
com.jogamp.common.util.ArrayHashMap.DEFAULT_INITIAL_CAPACITY
static final int DEFAULT_INITIAL_CAPACITY
The default initial capacity: {@value}.
Definition: ArrayHashMap.java:74
com.jogamp.common.util.ArrayHashMap.values
Collection< V > values()
Definition: ArrayHashMap.java:171
com.jogamp.common.util.ArrayHashMap.equals
final boolean equals(final Object arrayHashMap)
Definition: ArrayHashMap.java:278
com.jogamp.common.util.ArrayHashMap.toString
final String toString()
Definition: ArrayHashMap.java:145
com.jogamp.common.util.ArrayHashMap.DEFAULT_LOAD_FACTOR
static final float DEFAULT_LOAD_FACTOR
Default load factor: {@value}.
Definition: ArrayHashMap.java:70
com.jogamp.common.util.ArrayHashMap.entrySet
Set< java.util.Map.Entry< K, V > > entrySet()
Definition: ArrayHashMap.java:176
com.jogamp.common.util.ArrayHashMap.clear
final void clear()
Definition: ArrayHashMap.java:152
com.jogamp.common.util.ArrayHashMap.size
final int size()
Definition: ArrayHashMap.java:296
com.jogamp.common.util.ArrayHashMap.getData
final ArrayList< V > getData()
Returns this object ordered ArrayList.
Definition: ArrayHashMap.java:131
com.jogamp.common.util.ArrayHashMap.toArrayList
final ArrayList< V > toArrayList()
Definition: ArrayHashMap.java:137
com.jogamp.common.util.ArrayHashMap.keySet
Set< K > keySet()
Definition: ArrayHashMap.java:158
com.jogamp.common.util.ArrayHashMap.ArrayHashMap
ArrayHashMap(final ArrayHashMap< K, V > o)
Definition: ArrayHashMap.java:98
com.jogamp.common.util.ArrayHashMap.putAll
void putAll(final Map<? extends K, ? extends V > m)
Definition: ArrayHashMap.java:229
com.jogamp.common.util.ArrayHashMap.isEmpty
final boolean isEmpty()
Definition: ArrayHashMap.java:291
com.jogamp.common.util.ArrayHashMap.getMap
final HashMap< K, V > getMap()
Returns this object hash map.
Definition: ArrayHashMap.java:142
com.jogamp.common.util.ArrayHashMap.ArrayHashMap
ArrayHashMap(final boolean supportNullValue, final int initialCapacity, final float loadFactor)
Definition: ArrayHashMap.java:89
com.jogamp.common.util.ArrayHashMap.put
final V put(final K key, final V value)
Definition: ArrayHashMap.java:194