Compact HashMap : HashMap « Collections Data Structure « Java

Home
Java
1.2D Graphics GUI
2.3D
3.Advanced Graphics
4.Ant
5.Apache Common
6.Chart
7.Class
8.Collections Data Structure
9.Data Type
10.Database SQL JDBC
11.Design Pattern
12.Development Class
13.EJB3
14.Email
15.Event
16.File Input Output
17.Game
18.Generics
19.GWT
20.Hibernate
21.I18N
22.J2EE
23.J2ME
24.JavaFX
25.JDK 6
26.JDK 7
27.JNDI LDAP
28.JPA
29.JSP
30.JSTL
31.Language Basics
32.Network Protocol
33.PDF RTF
34.Reflection
35.Regular Expressions
36.Scripting
37.Security
38.Servlets
39.Spring
40.Swing Components
41.Swing JFC
42.SWT JFace Eclipse
43.Threads
44.Tiny Application
45.Velocity
46.Web Services SOA
47.XML
Java » Collections Data Structure » HashMap 




Compact HashMap
   
//package net.ontopia.utils;

import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;

public class CompactHashMap<K, V> extends AbstractMap<K, V> {
  protected final static int INITIAL_SIZE = 3;
  protected final static double LOAD_FACTOR = 0.6;

  /**
   * This object is used to represent null, should clients use that as a key.
   */
  protected final static Object nullObject = new Object();
  /**
   * When a key is deleted this object is put into the hashtable in its place,
   * so that other entries with the same key (collisions) further down the
   * hashtable are not lost after we delete an object in the collision chain.
   */
  protected final static Object deletedObject = new Object();
  protected int elements;
  protected int freecells;
  protected K[] keys;
  protected V[] values; // object at pos x corresponds to key at pos x
  protected int modCount;

  /**
   * Constructs a new, empty set.
   */
  public CompactHashMap() {
    this(INITIAL_SIZE);
  }

  /**
   * Constructs a new, empty set.
   */
  public CompactHashMap(int size) {
    // NOTE: If array size is 0, we get a
    // "java.lang.ArithmeticException: / by zero" in add(Object).
    keys = (K[]) new Object[(size == : size)];
    values = (V[]) new Object[(size == : size)];
    elements = 0;
    freecells = keys.length;
    modCount = 0;
  }

  // MAP IMPLEMENTATION 

  /**
   * Returns the number of key/value mappings in this map.
   */
  public int size() {
    return elements;
  }

  /**
   * Returns <tt>true</tt> if this map contains no mappings.
   */
  public boolean isEmpty() {
    return elements == 0;
  }

  /**
   * Removes all key/value mappings in the map.
   */
  public void clear() {
    elements = 0;
    for (int ix = 0; ix < keys.length; ix++) {
      keys[ixnull;
      values[ixnull;
    }
    freecells = values.length;
    modCount++;
  }

  /**
   * Returns <tt>true</tt> if this map contains the specified key.
   */
  public boolean containsKey(Object k) {
    return keys[findKeyIndex(k)] != null;
  }

  /**
   * Returns <tt>true</tt> if this map contains the specified value.
   */
  public boolean containsValue(Object v) {
    if (v == null)
      v = (VnullObject;

    for (int ix = 0; ix < values.length; ix++)
      if (values[ix!= null && values[ix].equals(v))
        return true;

    return false;
  }

  /**
   * Returns a read-only set view of the map's keys.
   */
  public Set<Entry<K, V>> entrySet() {
    throw new UnsupportedOperationException();
  }

  /**
   * Removes the mapping with key k, if there is one, and returns its value,
   * if there is one, and null if there is none.
   */
  public V remove(Object k) {
    int index = findKeyIndex(k);

    // we found the right position, now do the removal
    if (keys[index!= null) {
      // we found the object

      // same problem here as with put
      V v = values[index];
      keys[index(KdeletedObject;
      values[index(VdeletedObject;
      modCount++;
      elements--;
      return v;
    else
      // we did not find the key
      return null;
  }

  /**
   * Adds the specified mapping to this map, returning the old value for the
   * mapping, if there was one.
   */
  public V put(K k, V v) {
    if (k == null)
      k = (KnullObject;

    int hash = k.hashCode();
    int index = (hash & 0x7FFFFFFF% keys.length;
    int offset = 1;
    int deletedix = -1;

    // search for the key (continue while !null and !this key)
    while (keys[index!= null
        && !(keys[index].hashCode() == hash && keys[index].equals(k))) {

      // if there's a deleted mapping here we can put this mapping here,
      // provided it's not in here somewhere else already
      if (keys[index== deletedObject)
        deletedix = index;

      index = ((index + offset0x7FFFFFFF% keys.length;
      offset = offset * 1;

      if (offset == -1)
        offset = 2;
    }

    if (keys[index== null) { // wasn't present already
      if (deletedix != -1// reusing a deleted cell
        index = deletedix;
      else
        freecells--;

      modCount++;
      elements++;

      keys[index(Kk;
      values[index(Vv;

      // rehash with increased capacity
      if ((freecells / (doublekeys.length> LOAD_FACTOR)
        rehash(keys.length * 1);
      return null;
    else // was there already
      modCount++;
      V oldv = values[index];
      values[index(Vv;
      return oldv;
    }
  }

  /**
   * INTERNAL: Rehashes the hashmap to a bigger size.
   */
  protected void rehash(int newCapacity) {
    int oldCapacity = keys.length;
    K[] newKeys = (K[]) new Object[newCapacity];
    V[] newValues = (V[]) new Object[newCapacity];

    for (int ix = 0; ix < oldCapacity; ix++) {
      Object k = keys[ix];
      if (k == null || k == deletedObject)
        continue;

      int hash = k.hashCode();
      int index = (hash & 0x7FFFFFFF% newCapacity;
      int offset = 1;

      // search for the key
      while (newKeys[index!= null) { // no need to test for duplicates
        index = ((index + offset0x7FFFFFFF% newCapacity;
        offset = offset * 1;

        if (offset == -1)
          offset = 2;
      }

      newKeys[index(Kk;
      newValues[index= values[ix];
    }

    keys = newKeys;
    values = newValues;
    freecells = keys.length - elements;
  }

  /**
   * Returns the value for the key k, if there is one, and null if there is
   * none.
   */
  public V get(Object k) {
    return values[findKeyIndex(k)];
  }

  /**
   * Returns a virtual read-only collection containing all the values in the
   * map.
   */
  public Collection<V> values() {
    return new ValueCollection();
  }

  /**
   * Returns a virtual read-only set of all the keys in the map.
   */
  public Set<K> keySet() {
    return new KeySet();
  }

  // --- Internal utilities

  private final int findKeyIndex(Object k) {
    if (k == null)
      k = nullObject;

    int hash = k.hashCode();
    int index = (hash & 0x7FFFFFFF% keys.length;
    int offset = 1;

    // search for the key (continue while !null and !this key)
    while (keys[index!= null
        && !(keys[index].hashCode() == hash && keys[index].equals(k))) {
      index = ((index + offset0x7FFFFFFF% keys.length;
      offset = offset * 1;

      if (offset == -1)
        offset = 2;
    }
    return index;
  }

  // --- Key set

  private class KeySet<K> extends AbstractSet<K> {
    public int size() {
      return elements;
    }

    public boolean contains(Object k) {
      return containsKey(k);
    }

    public Iterator<K> iterator() {
      return new KeyIterator();
    }
  }

  private class KeyIterator<K> implements Iterator<K> {
    private int ix;

    private KeyIterator() {
      // walk up to first value, so that hasNext() and next() return
      // correct results
      for (; ix < keys.length; ix++)
        if (values[ix!= null && keys[ix!= deletedObject)
          break;
    }

    public boolean hasNext() {
      return ix < keys.length;
    }

    public void remove() {
      throw new UnsupportedOperationException("Collection is read-only");
    }

    public K next() {
      if (ix >= keys.length)
        throw new NoSuchElementException();
      K key = (Kkeys[ix++];

      // walk up to next value
      for (; ix < keys.length; ix++)
        if (keys[ix!= null && keys[ix!= deletedObject)
          break;

      // ix now either points to next key, or outside array (if no next)
      return key;
    }
  }

  // --- Value collection

  private class ValueCollection<V> extends AbstractCollection<V> {
    public int size() {
      return elements;
    }

    public Iterator<V> iterator() {
      return new ValueIterator();
    }

    public boolean contains(Object v) {
      return containsValue(v);
    }
  }

  private class ValueIterator<V> implements Iterator<V> {
    private int ix;

    private ValueIterator() {
      // walk up to first value, so that hasNext() and next() return
      // correct results
      for (; ix < values.length; ix++)
        if (values[ix!= null && values[ix!= deletedObject)
          break;
    }

    public boolean hasNext() {
      return ix < values.length;
    }

    public void remove() {
      throw new UnsupportedOperationException("Collection is read-only");
    }

    public V next() {
      if (ix >= values.length)
        throw new NoSuchElementException();
      V value = (Vvalues[ix++];

      // walk up to next value
      for (; ix < values.length; ix++)
        if (values[ix!= null && values[ix!= deletedObject)
          break;

      // ix now either points to next value, or outside array (if no next)
      return value;
    }
  }
}

   
    
    
  














Related examples in the same category
1.Iterate through the values of Java HashMap example
2.Get Synchronized Map from Java HashMap example
3.Check if a particular key exists in Java HashMap example
4.Check if a particular value exists in Java HashMap example
5.Get Set view of Keys from Java HashMap example
6.Get Size of Java HashMap
7.Remove all values from Java HashMap example
8.Remove value from Java HashMap
9.Create Java Hashtable from HashMap
10.Sort an HashMap based on the keys
11.For keys of a map
12.For values of a map
13.For both the keys and values of a map
14.Storing Primitive Types in a Collection
15.Creating a Copy of a Collection: the objects are not cloned.
16.Use Iterator to loop through the map key set
17.Generic hashmap with String as key and Integer as valueGeneric hashmap with String as key and Integer as value
18.Get key set and value set from map and use Iterator to loop through them
19.Clones a map
20.Hash map for counting references to Object keys.
21.Extended Version of java.util.HashMap that provides an extended get method accpeting a default value.
22.This class wraps a HashMap and provides methods by which key objects can be associated with "counting" values.
23.This extension of HashMap support duplicate keys
24.Concurrent Hopscotch HashMap
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.