Mega Code Archive

 
Categories / Java / Collections Data Structure
 

Random-access dictionary

// ArrayDictionary.java // $Id: ArrayDictionary.java,v 1.16 2000/08/16 21:37:57 ylafon Exp $ // (c) COPYRIGHT MIT and INRIA, 1996. // Please first read the full copyright statement in file COPYRIGHT.html import java.util.Dictionary; import java.util.Enumeration; import java.util.Vector; import java.io.DataInputStream; import java.io.InputStream; import java.io.PrintStream; /**  * Random-access dictionary:  * like a dictionary but with a certain Vector-ness to it  * Besides all the methods from Dictionary, it also has methods that  * permit direct access to the nth element or nth key.  * Should be used with care...it's not too well tested yet, and it  * is very exposed.  * <p>This class does <em>not</em> provide thread-safeness, for the sake of  * efficiency, again it should be used with care !  * @author Antonio Ram&iacute;rez  */ public class ArrayDictionary extends Dictionary implements Cloneable {     /** The array of keys */     protected Object[] keys ;     /** The array of corresponding values */     protected Object[] values ;     /** How many real elements are in */     protected int nelems ;     /** By how much to grow */     protected int incr ;     /**      * Create an ArrayDictionary using default values for initial size and      * increment.      */     public ArrayDictionary() {   this(10,10) ;     }     /**      * Create an ArrayDictionary using the given initial size.      * (The increment is set to the same value).      * @param init The initial size      */     public ArrayDictionary(int init) {   this(init,init) ;     }     /**      * Clone this array dictionary.      * <p>As for hashtables, a shallow copy is made, the keys and elements      * themselves are <em>not</em> cloned.      * @return The clone.      */     public Object clone() {   try {       ArrayDictionary cl = (ArrayDictionary) super.clone();       cl.values = new Object[values.length];       System.arraycopy(values, 0, cl.values, 0, values.length);       cl.keys = new Object[values.length];       System.arraycopy(keys, 0, cl.keys, 0, keys.length);       return cl;   } catch (CloneNotSupportedException ex) {       throw new InternalError();   }     }     /**      * Create an ArrayDictionary using the given initial size and      * the given increment for growing the array.      * @param init the initial size      * @param incr the increment      */     public ArrayDictionary(int init, int incr) {   keys = new Object[init] ;   values = new Object[init] ;   this.incr = incr ;   nelems = 0 ;     }     /**      * Create an ArrayDictionary, contructing the arrays of keys and      * values from the two given vectors.      * The two vectors should have the same size.      * The increment is set to the number of elements.      * @param keys the vector of keys      * @param values the vector of values      */     public ArrayDictionary(Vector keys,Vector values) {   this(keys,values,values.size()) ;     }     /**      * Create an ArrayDictionary, contructing the arrays of keys and      * values from the two given vectors.      * The two vectors should have the same size.      * @param keys the vector of keys      * @param values the vector of values      * @param incr the increment for growing the arrays      */     public ArrayDictionary(Vector keys, Vector values, int incr) {   this.incr = incr ;   nelems = keys.size() ;   this.keys = new Object[nelems] ;   this.values = new Object[nelems] ;   keys.copyInto(this.keys) ;   values.copyInto(this.values) ;     }     /**      * Create an ArrayDicitonary, <em>using</em> (not copying) the given pair      * of arrays as keys and values. The increment is set to the length of the      * arrays.       * @param keys the array of keys      * @param values the array of values      */     public ArrayDictionary(Object[] keys, Object[] values) {   this(keys,values,values.length) ;     }     /**      * Create an ArrayDicitonary, <em>using</em> (not copying) the given pair      * of arrays as keys and values.      * @param keys the array of keys      * @param values the array of values      * @param incr the increment for growing the arrays      */     public ArrayDictionary(Object[] keys, Object[] values, int incr) {   this.incr = incr ;   nelems = keys.length ;   this.keys = keys ;   this.values = values ;     }     protected final void grow() {   grow(keys.length+incr) ;     }     protected void grow(int newCapacity) {   Object[] newKeys = new Object[newCapacity] ;   Object[] newVals = new Object[newCapacity] ;   System.arraycopy(keys,0,newKeys,0,keys.length) ;   System.arraycopy(values,0,newVals,0,values.length) ;   keys = newKeys ;   values = newVals ;     }     /**      * Returns an enumeration of the elements of the dictionary.      * @return the enumeration      */     public Enumeration elements() {   return new ArrayEnumeration(values,nelems) ;     }     /**      * Returns the value that maps to the given key.      * @param key the key      * @return the value      */     public Object get(Object key) {   int n,i;   for(i=0,n=0;i<keys.length;i++) {       if(n >= nelems)     break ;       if ( keys[i] == null )     continue;       if(keys[i].equals(key))      return values[i] ;       n++ ;   }   return null;     }     /**      * "Optimized" method to obtain the values      * corresponding to several keys, in one swoop.      * @param rKeys An array of requested keys      * @return An array of corresponding values      */     public Object[] getMany(Object[] rKeys) {   Object[] rValues = new Object[rKeys.length] ;   int i,n ;   for(i=0,n=0;i<keys.length;i++) {       if(n >= nelems) break ;       if(keys[i]==null)     continue ;   inloop:       for(int j=0;j<rKeys.length;j++)      if(keys[i].equals(rKeys[j])) {         rValues[j] = values[i] ;         break inloop ;     }       n++ ;   }   return rValues ;     }          /**      * Are there any entries in the dictionary?      * @return <strong>true</strong> if there are no entries,      *         <strong>false></strong> otherwise.      */     public final boolean isEmpty() {   return nelems==0 ;     }     /**      * Increases the capacity of this dictionary to at least the      * specified number of key/value mappings.      * @param minCapacity the desired minimum capacity      */     public final void ensureCapacity(int minCapacity) {   if(minCapacity>keys.length) grow(minCapacity) ;     }     /**      * Returns an enumeration of the keys of the dictionary.      * @return the enumeration      */     public Enumeration keys() {   return new ArrayEnumeration(keys,nelems) ;     }     /**      * Adds a mapping between a key and a value to the dictionary.      * Will grow the arrays if necessary.      * @param key the key      * @param value the corresponding value      * @return the previous value corresponding to the key, or null if      *         the key is new.      */     public Object put(Object key,Object value) {   int empty = -1 ;   int i,n ;   for(i=0,n=0;i<keys.length;i++) {       if(n >= nelems)     break ;       if(keys[i] == null) {     empty = i ;     continue ;       }       if(keys[i].equals(key)) {     Object prev = values[i] ;     values[i]=value;     return prev ;       }       n++ ;   }   if(empty!=-1) {       keys[empty]=key ;       values[empty]=value ;       nelems++ ;   } else {       grow() ;       keys[nelems] = key ;       values[nelems++] = value ;   }   return null ;     }     /**      * Removes a key (and its value) from the dictionary;      * @param key the key to remove      * @return the value that used to map to that key      */     public Object remove(Object key) {   int i,n ;   for(i=0,n=0;i<keys.length;i++) {       if(n >= nelems)     break ;       if(keys[i] == null)     continue ;       if(keys[i].equals(key)) {     nelems-- ;     Object prev = values[i] ;     keys[i] = values[i] = null ;     return prev ;       }       n++ ;   }   return null ;     }     /**      * Returns the number of elements in the dictionary      * @return the number of elements      */     public final int size() { return nelems ; }     /**      * Returns the maximum number of keys the dictionary can hold      * without reallocating an array.      * @return the capacity of the dictionary      */     public final int capacity() { return keys.length ; }      /**      * Returns the nth key.      * @param n the index of the desired key      * @return the nth key, or null if no key in that place.      */     public final Object keyAt(int n) {   return keys[n] ;     }     /**      * Returns the nth element (value).      * @param n the index of the desired element      * @return the nth element, or null if no element in that place.      */     public final Object elementAt(int n) {   return values[n] ;     }     /**      * Sets the element at the nth place in the array.      * @param n the index of the element to change      * @param newVal the value to change it to      * @return the old value      */     public Object setElementAt(int n,Object newVal) {   Object prev = values[n] ;   values[n] = newVal ;   return prev ;     }     /**      * Removes the nth mapping (key/value pair) in the dictionary.      * @param n the index of the element to remove      * @return the old value of the element at the nth place      */     public Object removeElementAt(int n) {   if(values[n]!=null) {       Object prev = values[n] ;       values[n] = keys[n] = null ;       nelems--;       return prev;   } else return null ;     }     /**      * Creates a string representation of the dictionary      * @return the string representation.      */     public String toString() {   StringBuffer buf = new StringBuffer(100) ;   buf.append('[') ;   for(int i=0;i<keys.length;i++) {       if(keys[i]==null)     continue ;       buf.append(keys[i]) ;       buf.append('=') ;       buf.append(values[i]) ;       buf.append(' ') ;   }   buf.append(']') ;   return buf.toString() ;     }     /**      * A kludge for testing ArrayDictionary      */     public static void main(String[] args)     {   try {       PrintStream out = System.out ;       DataInputStream in = new DataInputStream(System.in) ;              String line = null ;       out.print("n ? ") ; out.flush() ;       line = in.readLine() ;       int n = Integer.parseInt(line) ;       ArrayDictionary ad = new ArrayDictionary(n) ;       String key = null, value = null;       while(true) {     out.print("action ? ") ; out.flush() ;     line = in.readLine() ;     switch(line.charAt(0)) {       case 'p':       case 'P':           out.print("key ? ") ; out.flush() ;           key = in.readLine() ;           out.print("value ? ") ; out.flush() ;           value = in.readLine() ;           value = (String ) ad.put(key,value) ;           out.println("old: "+value) ;           break ;       case 'r':       case 'R':           out.print("key ? ") ; out.flush() ;           key = in.readLine() ;           value = (String) ad.remove(key) ;           out.println("old: "+value) ;           break ;       case 'g':       case 'G':           out.print("key ? ") ; out.flush() ;           key = in.readLine() ;           value = (String) ad.get(key) ;           out.println("value: "+value) ;           break ;       case 'd':       case 'D':           out.println(ad.toString()) ;           break ;       case 'q':       case 'Q':           return ;     }       }   } catch(Exception ex) {       ex.printStackTrace() ;   }     } } //ArrayEnumeration.java //$Id: ArrayEnumeration.java,v 1.3 2000/08/16 21:37:57 ylafon Exp $ //(c) COPYRIGHT MIT and INRIA, 1996. //Please first read the full copyright statement in file COPYRIGHT.html /** Iterates through array skipping nulls. */ class ArrayEnumeration implements Enumeration {  private int nelems ;  private int elemCount ;  private int arrayIdx ;  private Object[] array ;  public ArrayEnumeration(Object[] array) { this(array,array.length) ;  }  public ArrayEnumeration(Object[] array,int nelems) { arrayIdx = elemCount = 0 ; this.nelems = nelems ; this.array = array ;  }  public final boolean hasMoreElements() { return elemCount<nelems ;  }  public final Object nextElement() { while(array[arrayIdx]==null && arrayIdx<array.length)    arrayIdx++ ; if(arrayIdx>=array.length)    throw new RuntimeException() ; elemCount++;  return array[arrayIdx++] ;  } }