📄 hashmapjava.cpp
字号:
/*
* A HashMap is an associative container that manages a set of key/value pairs.
* A pair is stored in a hashing structure based on the hash code of its key,
* which is obtained by using the standard hashCode() function.
* matched using a BinaryPredicate which is EqualTo() by default.
* keys are not allowed unless otherwise specified.
* A HashMap is useful for implementing a collection of one-to-one or
* one-to-many mappings.
* Insert ion can invalidate iterators.
* Removal can invalidate iterators. */
public class HashMap extends Map
{
static final int DEFAULT_SIZE = 203;
static final float DEFAULT_RATIO = 0.75F;
BinaryPredicate comparator ;
boolean allowDups ;
boolean expandActive = true ;
int size ;
HashMapNode [] buckets ; // Array of buckets. HashMapNode [ ] 。
int length ; // buckets.length, cached for speed.
int limit ;
float ratio ;
/*
* Construct myself to be an empty HashMap that compares key using equals()
* does not allow duplicates. */
public HashMap ()
{
this ( new EqualTo (), false , DEFAULT_SIZE , DEFAULT_RATIO );
}
/**
* Construct myself to be an empty HashMap that compares keys using equals()
* conditionally allows duplicates.
* @param allowDuplicates true if duplicates are allowed. */
public HashMap ( boolean allowDuplicates )
{
this ( new EqualTo (), allowDuplicates , DEFAULT_SIZE , DEFAULT_RATIO );
}
/**
* Construct myself to be an empty HashMap that compares keys using the specified
* binary predicate and does not allow duplicates.
*/
public HashMap ( BinaryPredicate comparator )
{
this ( comparator , false , DEFAULT_SIZE , DEFAULT_RATIO );
}
/**
* Construct myself to be an empty HashMap that compares keys using the specified
* binary predicate and conditionally allows duplicates.
*/
public HashMap ( BinaryPredicate comparator , boolean allowDuplicates )
{
this ( comparator , allowDuplicates , DEFAULT_SIZE , DEFAULT_RATIO ); 今 ( 比较 , allowDuplicates ,
DEFAULT_SIZE , DEFAULT_RATIO ) ;
}
/**
* Construct myself to be an empty HashMap that compares keys using the specified
* binary predicate. The initial buckets and load ratio must also be specified.
*/
public HashMap ( BinaryPredicate comparator , int capacity , float loadRatio )
{
this ( comparator , false , capacity , loadRatio );
}
/**
* Construct myself to be an empty HashMap that compares keys using the specified
* binary predicate and conditionally allows duplicates.
* load ratio must also be specified. 。
* @param comparator The predicate for comparing keys.
* @param allowDuplicates true if duplicates are allowed.
* @param capacity The initial number of hash buckets to reserve.
* @param loadRatio The maximum load ratio.
*/
public HashMap ( BinaryPredicate comparator , boolean allowDuplicates , int capacity , float loadRatio )
{
this . comparator = comparator ;
ratio = loadRatio ;
length = capacity ;
limit = ( int )( length * ratio );
buckets = new HashMapNode [ length ];
allowDups = allowDuplicates ;
}
/**
* Construct myself to be a shallow copy of an existing HashMap.
* @param map The HashMap to copy.
*/
public HashMap ( HashMap map )
{
copy ( map );
}
/**
* Return true if I allow duplicate keys. 。
*/
public boolean allowsDuplicates ()
{
return allowDups ;
}
/**
* Return my comparator.
*/
public BinaryPredicate getComparator ()
{
return comparator ;
}
/**
* Return my load ratio.
*/
public float getLoadRatio ()
{
return ratio ;
}
/**
* Return a shallow copy of myself.
*/
public synchronized Object clone ()
{
return new HashMap ( this );
}
/**
* Become a shallow copy of an existing HashMap.
* @param map The HashMap that I shall become a shallow copy of.
。
*/
public synchronized void copy ( HashMap map )
{
synchronized ( map )
{
comparator = map . comparator ;
length = map . length ;
ratio = map . ratio ;
limit = map . limit ;
size = map . size ();
buckets = new HashMapNode [ length ];
allowDups = map . allowDups ;
for ( int i = 0; i < length ; i ++ )
{
HashMapNode oldNode = null ;
HashMapNode node = map . buckets [ i ];
while ( node != null )
{
HashMapNode newNode = new HashMapNode ();
newNode . key = node . key ;
newNode . value = node . value ;
newNode . hash = node . hash ;
if ( buckets [ i ] == null )
buckets [ i ] = newNode ;
else
oldNode . next = newNode ;
oldNode = newNode ;
node = node . next ;
}
}
}
/**
* Return a string that describes me.
*/
public synchronized String toString ()
{
return Printing . toString ( this , "HashMap" );
}
/**
* Return an Enumeration to my values.
*/
public synchronized Enumeration elements ()
{
return new HashMapIterator ( first (), this , HashMapIterator . VALUE );
}
/**
* Return an iterator positioned at my first pair.
*/
public ForwardIterator start ()
{
return begin ();
}
/**
* Return an iterator positioned immediately afer my last pair.
*/
public ForwardIterator finish ()
{
return end ();
}
/**
* Return an iterator positioned at my first pair.
*/
public synchronized HashMapIterator begin ()
{
return new HashMapIterator ( first (), this , HashMapIterator . PAIR );
}
/**
* Return an iterator positioned immediately after my last pair.
*/
public synchronized HashMapIterator end ()
{
return new HashMapIterator ( null , this , HashMapIterator . PAIR );
}
/**
* Return true if I contain no entries.
*/
public boolean isEmpty ()
{
return size == 0;
}
/**
* Return the number of entries that I contain.
*/
public int size ()
{
return size ;
}
/**
* Return the maximum number of entries that I can contain.
*/
public int maxSize ()
{
return Allocator . maxSize ();
}
/**
* Return true if I'm equal to another object.
* @param object The object to compare myself against.
*/
public boolean equals ( Object object )
{
return object instanceof HashMap && equals ( ( HashMap ) object );
}
/**
* Return true if I contain exactly the same key/value pairs as another HashMap.
* Use equals() to compare values.
* @param map The HashMap to compare myself against.
*/
public synchronized boolean equals ( HashMap map )
{
synchronized ( map )
{
if ( size () != map . size () )
return false ;
if ( allowDups )
{
Object previous = null ;
for ( HashMapIterator iterator = begin (); iterator . hasMoreElements (); iterator . advance () )
{
Object key = iterator . key ();
// Execute the following code for each unique key in the source.
if ( previous == null || ! key . equals ( previous ) )
{
previous = key ;
if ( ! same ( values ( key ), map . values ( key ) ) )
return false ;
}
}
}
else
{ (
for ( HashMapIterator iterator = begin (); iterator . hasMoreElements (); iterator . advance () )
{
Object value = map . get ( iterator . key () );
if ( value == null || ! value . equals ( iterator . value () ) )
return false ;
}
}
}
return true ;
}
/**
* Return my hash code for support of hashing containers
*/
public synchronized int hashCode ()
{
ForwardIterator start = new HashMapIterator ( first (), this , HashMapIterator . KEY );
ForwardIterator end = new HashMapIterator ( null , this , HashMapIterator . KEY );
return Hashing . unorderedHash ( start , end );
}
/**
* Swap my contents with another HashMap.
* @param map The HashMap that I will swap my contents with.
*/
public synchronized void swap ( HashMap map )
{
synchronized ( map )
{
int tmpSize = size ;
size = map . size ();
map . size ( tmpSize );
HashMapNode [] tmpBuckets = buckets ;
buckets = map . buckets ;
map . buckets = tmpBuckets ;
int tmpLength = length ;
length = map . length ;
map . length = tmpLength ;
int tmpLimit = limit ;
limit = map . limit ;
map . limit = tmpLimit ;
float tmpRatio = ratio ;
ratio = map . ratio ;
map . ratio = tmpRatio ;
boolean tmpDups = allowDups ;
allowDups = map . allowDups ;
map . allowDups = tmpDups ;
}
}
/**
* Remove all of my elements.
*/
public synchronized void clear ()
{
buckets = new HashMapNode [ length ];
size = 0;
}
/**
* Remove all key/value pairs that match a particular key.
* @param key The key of the pair(s) to be removed.
* @return Return the first object removed or null if not changed.
*/
public Object remove ( Object key )
{
return removeAux ( key , size ). first ;
}
/**
* Remove at most a given number of key/value pairs that match a particular key.
* @param key The key of the pair(s) to be removed.
* @param count The maximum number of the pair(s) to remove.
* @return Return the number of pairs removed.
*/
public int remove ( Object key , int count )
{
Pair result = removeAux ( key , count );
return ( ( Number ) result . second ). intValue ();
}
synchronized Pair removeAux ( Object key , int maximum )
{
if ( maximum > 0 )
{
int hash = key . hashCode () & 0x7FFFFFFF;
int probe = hash % length ;
for ( HashMapNode node = buckets [ probe ], previous = null ; node != null ; previous = node ,
node = node . next )
if ( node . hash == hash && comparator . execute ( node . key , key ) )
{
int count = 1;
-- maximum ;
HashMapNode end = node . next ;
Object value = node . value ; // we only want the first one.
if ( allowDups )
{
while ( maximum > 0 && end != null && end . hash == hash && comparator . execute ( end .
key , key ) )
{
++ count ;
-- maximum ;
end = end . next ;
}
}
if ( previous == null )
buckets [ probe ] = end ;
else
previous . next = end ;
size -= count ;
return new Pair ( value , new Integer ( count ) );
}
}
return new Pair ( null , new Integer ( 0 ) );
}
/** / **
* Remove the element at a particular position.
* @param e An Enumeration positioned at the element to remove.
* @exception IllegalArgumentException is the Enumeration isn't a
* HashMapIterator for this HashMap object.
* @return Return the value associated with the enumeration.
*/
public synchronized Object remove ( Enumeration e )
{
if ( ! ( e instanceof HashMapIterator ) )
throw new IllegalArgumentException ( "Enumeration not a HashMapIterator" );
if ( (( HashMapIterator ) e ). myHashMap != this )
throw new IllegalArgumentException ( "Enumeration not for this HashMap" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -