public class Hashtable
extends Dictionary
implements Map, Cloneable, Serializable
This class implements a hashtable, which maps keys to values. Any non-null object can be used as a key or as a value. To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method. An instance of Hashtable has two parameters that affect its performance: initial capacity and load factor. The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. Note that the hash table is open: in the case a "hash collision", a single bucket stores multiple entries, which must be searched sequentially. The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hashtable exceeds the product of the load factor and the current capacity, the capacity is increased by calling the rehash method.Generally, the default load factor (.75) offers a good tradeoff between time and space costs. Higher values decrease the space overhead but increase the time cost to look up an entry (which is reflected in most Hashtable operations, including get and put).The initial capacity controls a tradeoff between wasted space and the need for rehash operations, which are time-consuming. No rehash operations will ever occur if the initial capacity is greater than the maximum number of entries the Hashtable will contain divided by its load factor. However, setting the initial capacity too high can waste space.If many entries are to be made into a Hashtable, creating it with a sufficiently large capacity may allow the entries to be inserted more efficiently than letting it perform automatic rehashing as needed to grow the table. This example creates a hashtable of numbers. It uses the names of the numbers as keys: 
     Hashtable numbers = new Hashtable();
     numbers.put("one", new Integer(1));
     numbers.put("two", new Integer(2));
     numbers.put("three", new Integer(3));
 To retrieve a number, use the following code: 
     Integer n = (Integer)numbers.get("two");
     if (n != null) {
         System.out.println("two = " + n);
     }
 As of the Java 2 platform v1.2, this class has been retrofitted to implement Map, so that it becomes a part of Java's collection framework. Unlike the new collection implementations, Hashtable is synchronized.The Iterators returned by the iterator and listIterator methods of the Collections returned by all of Hashtable's "collection view methods" are fail-fast: if the Hashtable is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the Iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. The Enumerations returned by Hashtable's keys and values methods are not fail-fast. Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs. 

解决方案 »

  1.   

    简单来说,hash就是找到一种数据内容和数据存放地址之间的映射关系。比如,由若干字符串要存放到一个哈西表中,希望能够在O(1)的时间内在表中定位某个特定的字符串,我们可以用数组来实现哈西表,找到某种函数sting -> integer,记为 p = f(s),其中p是一个整数,s是一个字符串,p就是字符串s在数组中的下标。这样如果需要在数组中定位s,只要直接根据函数p=f(s)就可以计算s的位置。在哈西表中添加一个字符串也类似,根据字符串的值计算出其应该存放在数组中的位置,然后将字符串放入。但是这种函数(成为哈西函数)很难找,找到一个一一对应的函数几乎不可能,所以经常采用非一一对应的哈西函数。比如对于上面的例子,我们可以设计一个简单的哈西函数,我们设f(s)定义为s的各个字符的Ascii码的和除以n的余数,这里n是我们的数组的长度,我们假设了哈西表中最多需要存储n个元素。但是这个哈西函数有个显而易见的缺点,比如对于字符串s1= "abc"和s2="acb",显然计算出来的哈西函数值都是一样的,但是一个位置上只能存放一个元素,如果先将s1放入哈西表的位置p1,再将s2放入哈西表,这时候因为计算出p2=f(s2) = p1,所以s2应该放置的位置已经被s1占据了,所以就出现了麻烦。这就叫做“冲突”。解决这个冲突的一个简单的办法是,因为p1已经被s1占据,我们就看p1+1,如果该位置为空,则放入s2,否则继续看p1+2,……一直找到一个空位。假设我们将s2放在p1+1,但是这时候要加入s3,而f(s3)恰好等于p1+1,s3的位置又被s2占据了,我们可以继续看p1+2,p1+3……是否为空,直到找到一个空位放入s3,依此类推。在查找s2的时候,我们先根据f(s2)计算出s2应该在p1位置上,然后我们看p1位置上的元素,发现不是s2(该位置上是s1),于是我们继续看p1+1,p1+2,……一直到找到s2,或者到表尾,或者发现一个空位就可以中止了,后两种情况表示s2不在表中。显而易见,如果冲突发生的太多的话,哈西表的效率会下降。事实上我刚才举的例子中的哈西函数很不好,所以冲突发生的可能性很大。如果找一个比较好的哈西函数,哈西表的效率还是很高的。至于找哈西函数的方法,要根据具体的数据类型和应用场合来分析,也有一些原则,这里就不一一介绍了~~摘抄: http://dev.csdn.net/develop/article/12/12981.shtm