Array map : Map « Collections Data Structure « Java






Array map

/* * Copyright 2008-2009 the T2 Project ant the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *///package org.t2framework.commons.util; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.lang.reflect.Array; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; /** * Array map. * * @author shot * * @param <K> * @param <V> */publicclass ArrayMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Externalizable { staticfinallong serialVersionUID = 1L; protectedstaticfinalint INITIAL_CAPACITY = 17; protectedstaticfinalfloat LOAD_FACTOR = 0.75f; protectedtransientint threshold; protectedtransient Entry<K, V>[] mapTable; protectedtransient Entry<K, V>[] listTable; protectedtransientint size = 0; protectedtransient Set<?> entrySet = null; publicstatic <K, V> ArrayMap<K, V> newArrayMap() { returnnew ArrayMap<K, V>(); } public ArrayMap() { this(INITIAL_CAPACITY); } @SuppressWarnings("unchecked") public ArrayMap(int initialCapacity) { if (initialCapacity <= 0) { initialCapacity = INITIAL_CAPACITY; } mapTable = new Entry[initialCapacity]; listTable = new Entry[initialCapacity]; threshold = (int) (initialCapacity * LOAD_FACTOR); } public ArrayMap(Map<K, V> map) { this((int) (map.size() / LOAD_FACTOR) + 1); putAll(map); } publicfinalint size() { return size; } publicfinalboolean isEmpty() { return size == 0; } publicfinalboolean containsValue(Object value) { return indexOf(value) >= 0; } publicfinalint indexOf(Object value) { if (value != null) { for (int i = 0; i < size; i++) { if (value.equals(listTable[i].value_)) { return i; } } } else { for (int i = 0; i < size; i++) { if (listTable[i].value_ == null) { return i; } } } return -1; } publicboolean containsKey(final Object key) { Entry<K, V>[] tbl = mapTable; if (key != null) { int hashCode = key.hashCode(); int index = (hashCode & 0x7FFFFFFF) % tbl.length; for (Entry<K, V> e = tbl[index]; e != null; e = e.next_) { if (e.hashCode_ == hashCode && key.equals(e.key_)) { return true; } } } else { for (Entry<K, V> e = tbl[0]; e != null; e = e.next_) { if (e.key_ == null) { return true; } } } return false; } public V get(final Object key) { Entry<K, V>[] tbl = mapTable; if (key != null) { int hashCode = key.hashCode(); int index = (hashCode & 0x7FFFFFFF) % tbl.length; for (Entry<K, V> e = tbl[index]; e != null; e = e.next_) { if (e.hashCode_ == hashCode && key.equals(e.key_)) { return e.value_; } } } else { for (Entry<K, V> e = tbl[0]; e != null; e = e.next_) { if (e.key_ == null) { return e.value_; } } } return null; } publicfinal V get(finalint index) { return getEntry(index).value_; } publicfinal K getKey(finalint index) { return getEntry(index).key_; } publicfinal Entry<K, V> getEntry(finalint index) { if (index >= size) { thrownew IndexOutOfBoundsException("Index:" + index + ", Size:" + size); } return listTable[index]; } public V put(final K key, final V value) { int hashCode = 0; int index = 0; if (key != null) { hashCode = key.hashCode(); index = (hashCode & 0x7FFFFFFF) % mapTable.length; for (Entry<K, V> e = mapTable[index]; e != null; e = e.next_) { if ((e.hashCode_ == hashCode) && key.equals(e.key_)) { return swapValue(e, value); } } } else { for (Entry<K, V> e = mapTable[0]; e != null; e = e.next_) { if (e.key_ == null) { return swapValue(e, value); } } } ensureCapacity(); index = (hashCode & 0x7FFFFFFF) % mapTable.length; Entry<K, V> e = new Entry<K, V>(hashCode, key, value, mapTable[index]); mapTable[index] = e; listTable[size++] = e; return null; } publicfinalvoid set(finalint index, final V value) { getEntry(index).setValue(value); } public V remove(final Object key) { Entry<K, V> e = removeMap(key); if (e != null) { V value = e.value_; removeList(indexOf(e)); e.clear(); return value; } return null; } publicfinal Object remove(int index) { Entry<K, V> e = removeList(index); Object value = e.value_; removeMap(e.key_); e.value_ = null; return value; } @SuppressWarnings("unchecked") @Override publicvoid putAll(Map<? extends K, ? extends V> map) { for (Iterator<?> i = map.entrySet().iterator(); i.hasNext();) { Map.Entry<K, V> e = (Map.Entry<K, V>) i.next(); put(e.getKey(), e.getValue()); } } publicfinalvoid clear() { for (int i = 0; i < mapTable.length; i++) { mapTable[i] = null; } for (int i = 0; i < listTable.length; i++) { listTable[i] = null; } size = 0; } publicfinal Object[] toArray() { Object[] array = new Object[size]; for (int i = 0; i < array.length; i++) { array[i] = get(i); } return array; } publicfinal Object[] toArray(final Object proto[]) { Object[] array = proto; if (proto.length < size) { array = (Object[]) Array.newInstance(proto.getClass() .getComponentType(), size); } for (int i = 0; i < array.length; i++) { array[i] = get(i); } if (array.length > size) { array[size] = null; } return array; } @SuppressWarnings("unchecked") publicfinalboolean equals(Object o) { if (!getClass().isInstance(o)) { return false; } ArrayMap<K, V> e = (ArrayMap<K, V>) o; if (size != e.size) { return false; } for (int i = 0; i < size; i++) { if (!listTable[i].equals(e.listTable[i])) { return false; } } return true; } @SuppressWarnings("unchecked") publicfinal Set entrySet() { if (entrySet == null) { entrySet = new AbstractSet() { public Iterator iterator() { returnnew ArrayMapIterator(); } publicboolean contains(Object o) { if (!(o instanceof Entry)) { return false; } Entry entry = (Entry) o; int index = (entry.hashCode_ & 0x7FFFFFFF) % mapTable.length; for (Entry e = mapTable[index]; e != null; e = e.next_) { if (e.equals(entry)) { return true; } } return false; } publicboolean remove(Object o) { if (!(o instanceof Entry)) { return false; } Entry entry = (Entry) o; return ArrayMap.this.remove(entry.key_) != null; } publicint size() { return size; } publicvoid clear() { ArrayMap.this.clear(); } }; } return entrySet; } publicfinalvoid writeExternal(final ObjectOutput out) throws IOException { out.writeInt(listTable.length); out.writeInt(size); for (int i = 0; i < size; i++) { out.writeObject(listTable[i].key_); out.writeObject(listTable[i].value_); } } @SuppressWarnings("unchecked") publicfinalvoid readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { int num = in.readInt(); mapTable = new Entry[num]; listTable = new Entry[num]; threshold = (int) (num * LOAD_FACTOR); int size = in.readInt(); for (int i = 0; i < size; i++) { K key = (K) in.readObject(); V value = (V) in.readObject(); put(key, value); } } public Object clone() { ArrayMap<K, V> copy = new ArrayMap<K, V>(); copy.threshold = threshold; copy.mapTable = mapTable; copy.listTable = listTable; copy.size = size; return copy; } privatefinalint indexOf(final Entry<K, V> entry) { for (int i = 0; i < size; i++) { if (listTable[i] == entry) { return i; } } return -1; } privatefinal Entry<K, V> removeMap(Object key) { int hashCode = 0; int index = 0; if (key != null) { hashCode = key.hashCode(); index = (hashCode & 0x7FFFFFFF) % mapTable.length; for (Entry<K, V> e = mapTable[index], prev = null; e != null; prev = e, e = e.next_) { if ((e.hashCode_ == hashCode) && key.equals(e.key_)) { if (prev != null) { prev.next_ = e.next_; } else { mapTable[index] = e.next_; } return e; } } } else { for (Entry<K, V> e = mapTable[index], prev = null; e != null; prev = e, e = e.next_) { if ((e.hashCode_ == hashCode) && e.key_ == null) { if (prev != null) { prev.next_ = e.next_; } else { mapTable[index] = e.next_; } return e; } } } return null; } privatefinal Entry<K, V> removeList(int index) { Entry<K, V> e = listTable[index]; int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(listTable, index + 1, listTable, index, numMoved); } listTable[--size] = null; return e; } @SuppressWarnings("unchecked") privatefinalvoid ensureCapacity() { if (size >= threshold) { Entry<K, V>[] oldTable = listTable; int newCapacity = oldTable.length * 2 + 1; Entry<K, V>[] newMapTable = new Entry[newCapacity]; Entry<K, V>[] newListTable = new Entry[newCapacity]; threshold = (int) (newCapacity * LOAD_FACTOR); System.arraycopy(oldTable, 0, newListTable, 0, size); for (int i = 0; i < size; i++) { Entry<K, V> old = oldTable[i]; int index = (old.hashCode_ & 0x7FFFFFFF) % newCapacity; Entry<K, V> e = old; old = old.next_; e.next_ = newMapTable[index]; newMapTable[index] = e; } mapTable = newMapTable; listTable = newListTable; } } privatefinal V swapValue(final Entry<K, V> entry, final V value) { V old = entry.value_; entry.value_ = value; return old; } privateclass ArrayMapIterator implements Iterator<Entry<K, V>> { privateint current_ = 0; privateint last_ = -1; publicboolean hasNext() { return current_ != size; } public Entry<K, V> next() { try { Entry<K, V> n = listTable[current_]; last_ = current_++; return n; } catch (IndexOutOfBoundsException e) { thrownew NoSuchElementException(); } } publicvoid remove() { if (last_ == -1) { thrownew IllegalStateException(); } ArrayMap.this.remove(last_); if (last_ < current_) { current_--; } last_ = -1; } } privatestaticclass Entry<K, V> implements Map.Entry<K, V>, Externalizable { privatestaticfinallong serialVersionUID = -6625980241350717177L; transientint hashCode_; transient K key_; transient V value_; transient Entry<K, V> next_; public Entry(finalint hashCode, final K key, final V value, final Entry<K, V> next) { hashCode_ = hashCode; key_ = key; value_ = value; next_ = next; } public K getKey() { return key_; } public V getValue() { return value_; } public V setValue(final V value) { V oldValue = value_; value_ = value; return oldValue; } publicvoid clear() { key_ = null; value_ = null; next_ = null; } @SuppressWarnings("unchecked") publicboolean equals(final Object o) { if (this == o) { return true; } Entry<K, V> e = (Entry<K, V>) o; return (key_ != null ? key_.equals(e.key_) : e.key_ == null) && (value_ != null ? value_.equals(e.value_) : e.value_ == null); } publicint hashCode() { return hashCode_; } public String toString() { return key_ + "=" + value_; } publicvoid writeExternal(final ObjectOutput s) throws IOException { s.writeInt(hashCode_); s.writeObject(key_); s.writeObject(value_); s.writeObject(next_); } @SuppressWarnings("unchecked") publicvoid readExternal(final ObjectInput s) throws IOException, ClassNotFoundException { hashCode_ = s.readInt(); key_ = (K) s.readObject(); value_ = (V) s.readObject(); next_ = (Entry) s.readObject(); } } } ------------------- /* * Copyright 2008-2009 the T2 Project ant the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.t2framework.commons.util; import org.t2framework.commons.util.ArrayMap; import junit.framework.TestCase; publicclass ArrayMapTest extends TestCase { publicvoid test1() throws Exception { ArrayMap<String, String> map = ArrayMap.newArrayMap(); map.put("aaa", "AAA"); map.put("bbb", "BBB"); assertEquals("AAA", map.get(0)); assertEquals("BBB", map.get("bbb")); } publicvoid test2() throws Exception { ArrayMap<String, String> map = ArrayMap.newArrayMap(); map.put("aaa", "AAA"); map.put("bbb", "BBB"); ArrayMap<String, String> map2 = ArrayMap.newArrayMap(); map2.put("ccc", "CCC"); map2.putAll(map); assertEquals("CCC", map2.get(0)); assertEquals("BBB", map2.get("bbb")); } publicvoid test3() throws Exception { ArrayMap<String, String> map = ArrayMap.newArrayMap(); { map.put("a", "A"); map.put("b", "B"); map.put("c", "C"); } String key = map.getKey(0); assertEquals("a", key); assertTrue(map.containsKey("b")); assertTrue(map.containsValue("A")); assertEquals("C", map.get("c")); assertTrue(map.indexOf("B") == 1); Object[] array = map.toArray(); assertTrue(array.length == 3); assertEquals("B", array[1]); } } 








Related examples in the same category

1.Creating and storing arrays in a map
2.Sort based on the values
3.Get a key from value with an HashMap
4.Retrieve environment variables (JDK1.5)
5.Creating a Type-Specific Map: creates a map whose keys are Integer objects and values are String objects.
6.A map declared to hold objects of a type T can also hold objects that extend from T
7.A value retrieved from a type-specific collection does not need to be casted
8.Map techniques.
9.Create an array containing the keys in a map
10.Create an array containing the values in a map
11.Creating a Hash Table
12.Creating a Map That Retains Order-of-Insertion
13.Automatically Removing an Unreferenced Element from a Hash Table
14.Creating a Type-Specific Map [5.0]
15.Use Iterator to loop through the HashMap class
16.Create type specific collections
17.Convert Properties into Map
18.A java.util.Map implementation using reference values
19.Utility method that return a String representation of a map. The elements will be represented as "key = value"
20.Utility method that return a String representation of a map. The elements will be represented as "key = value" (tab)
21.This program demonstrates the use of a map with key type String and value type Employee
22.Format a Map
23.A Map implementation that dumps its content when memory runs low.
24.A Map that stores the values in files within a directory.
25.Map List
26.Multi Value Map Array List
27.Multi Value Map Linked HashSet
28.An object that maps keys to values, and values back to keys.
29.LRU Map
30.A map acts like array.
31.Order Retaining Map
32.BinaryMap class implements a map from objects to integer objects where the only value is the integer with value 1.
33.A space-optimized map for associating char keys with values.
34.A Map implementation that grows to a fixed size and then retains only a fixed number of the highest (largest) keys.
35.Class which creates mapping between keys and a list of values.
36.A map of values by class.
37.History Map
38.Sorts map by values in ascending order.
39.Map from a given key to a list of values
40.Map from a given key to a set of values
41.Class which keeps a set of values and assigns each value a unique positive index.
42.Array Map
43.An ArrayMap is a very inefficient map type that is more robust in dealing with changes to its keys than other maps.
44.This Map stores it's keys as strings in upper case, null and duplicate keys are not allowed
45.Map to string
46.A simple class that stores key Strings as char[]'s in a hash table.
close