不用多说,看下面的程序就可以:
HashMap map = new HashMap();
map.put( "Null" , null );
map.put( null , "Null" );
map.put( null , "Empty" );
System. out .println(map.get( null ));
System. out .println(map.get( "Null" ));
System. out .println(map.get( "NullThere" ));
System. out .println(map.containsKey ( "Null" ));
System. out .println(map.containsKey ( "NullThere" ));
输出结果为:
Empty
null
null
true
false
| HashMap | Hashtable |
继承,实现 | HashMap <K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable | Hashtable <K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable,Serializable |
多线程,同步 | 未同步的,可以使用 Colletcions 进行同步 Map Collections.synchronizedMap(Map m) | 已经同步过的可以安全使用 |
对null 的处理 | HashMap map = new HashMap(); map.put( null , "Null" ); map.put( "Null" , null ); map.containsKey( null ); map.containsValue( null ); 以上这 5 条语句无论在编译期,还是在运行期都是没有错误的 . 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。 | Hashtable table = new Hashtable(); table.put(null, "Null"); table.put("Null", null); table.contains(null); table.containsKey(null); table.containsValue(null); 后面的 5 句话在编译的时候不会有异常,可在运行的时候会报空指针异常 具体原因可以查看源代码 public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } …………. |
增长率 | void addEntry( int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table [bucketIndex]; table [bucketIndex] = new Entry<K,V>(hash, key, value, e); if ( size ++ >= threshold ) resize (2 * table . length ); } | protected void rehash() { int oldCapacity = table . length ; Entry[] oldMap = table ; int newCapacity = oldCapacity * 2 + 1; Entry[] newMap = new Entry[newCapacity]; modCount ++; threshold = ( int )(newCapacity * loadFactor ); table = newMap; for ( int i = oldCapacity ; i-- > 0 ;) { for (Entry<K,V> old = oldMap[i] ; old != null ; ) { Entry<K,V> e = old; old = old. next ; int index = (e. hash & 0x7FFFFFFF) % newCapacity; e. next = newMap[index]; newMap[index] = e; } } }
|
哈希值的使用 | HashMap 重新计算 hash 值,而且用与代替求模 public boolean containsKey(Object key) { Object k = maskNull(key); int hash = hash(k.hashCode()); int i = indexFor(hash, table.length); Entry e = table[i]; while (e != null ) { if (e.hash == hash && eq(k, e.key)) return true ; e = e.next; } return false ; } | HashTable 直接使用对象的 hashCode ,代码是这样的: public synchronized boolean containsKey(Object key) { Entry tab[] = table ; int hash = key.hashCode (); int index = (hash & 0x7FFFFFFF) % tab. length ; for (Entry<K,V> e = tab[index] ; e != null ; e = e. next ) { if ((e. hash == hash) && e. key .equals(key)) { return true ; } } return false ; } |
引用自:http://www.99inf.net/SoftwareDev/Java/53925.htm