天天看点

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

     上一章我们学习了hashmap的源码,这一节我们来讨论一下hashtable,hashtable和hashmap在某种程度上是类似的。我们依然遵循以下步骤:先对hashtable有个整体的认识,然后学习它的源码,深入剖析hashtable。

        首先看一下hashtable的继承关系

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

java.lang.object  

   ↳     java.util.dictionary<k, v>  

         ↳     java.util.hashtable<k, v>  

public class hashtable<k,v> extends dictionary<k,v>  

    implements map<k,v>, cloneable, java.io.serializable { }  

        我们可以看出,hashtable不但继承了dictionary,而且实现了map、cloneable和serializable接口,所以hashtable也可以实例化。hashtable和hashmap不同,hashtable是线程安全的(等会我们在源码中就能看出)。下面我们先总览一下hashtable都有哪些api,然后我们详细分析它们。

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

synchronized void                clear()  

synchronized object              clone()  

             boolean             contains(object value)  

synchronized boolean             containskey(object key)  

synchronized boolean             containsvalue(object value)  

synchronized enumeration<v>      elements()  

synchronized set<entry<k, v>>    entryset()  

synchronized boolean             equals(object object)  

synchronized v                   get(object key)  

synchronized int                 hashcode()  

synchronized boolean             isempty()  

synchronized set<k>              keyset()  

synchronized enumeration<k>      keys()  

synchronized v                   put(k key, v value)  

synchronized void                putall(map<? extends k, ? extends v> map)  

synchronized v                   remove(object key)  

synchronized int                 size()  

synchronized string              tostring()  

synchronized collection<v>       values()  

        从hashtable的api中可以看出,hashtable之所以是线程安全的,是因为方法上都加了synchronized关键字。

        和hashmap一样,hashtable内部也维护了一个数组,数组中存放的是entry<k,v>实体,数组定义如下:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

private transient entry<k,v>[] table;  

        然后我们看看entry实体的定义:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

/** 

 * entry实体类的定义 

 */  

private static class entry<k,v> implements map.entry<k,v> {  

    int hash; //哈希值  

    final k key;  

    v value;  

    entry<k,v> next; //指向的下一个entry,即链表的下一个节点  

    //构造方法  

    protected entry(int hash, k key, v value, entry<k,v> next) {  

        this.hash = hash;  

        this.key =  key;  

        this.value = value;  

        this.next = next;  

    }  

    //由于hashtable实现了cloneable接口,所以支持克隆操作  

    protected object clone() {  

        return new entry<>(hash, key, value, (next==null ? null : (entry<k,v>) next.clone()));  

    //下面对map.entry的具体操作了  

    public k getkey() { //拿到key  

        return key;  

    public v getvalue() { //拿到value  

        return value;  

    public v setvalue(v value) { //设置value  

        if (value == null) //从这里可以看出,hashtable中的value是不允许为空的!  

            throw new nullpointerexception();  

        v oldvalue = this.value;  

        return oldvalue;  

    //判断两个entry是否相等  

    public boolean equals(object o) {  

        if (!(o instanceof map.entry))  

            return false;  

        map.entry<?,?> e = (map.entry)o;  

        //必须两个entry的key和value均相等才行  

        return key.equals(e.getkey()) && value.equals(e.getvalue());  

    public int hashcode() { //计算hashcode  

        return (objects.hashcode(key) ^ objects.hashcode(value));  

    public string tostring() { //重写tostring方法  

        return key.tostring()+"="+value.tostring();  

}  

        从entry实体的源码中可以看出,hashtable其实就是个存储entry的数组,entry中包含了键值对以及下一个entry(用来处理冲突的),形成链表。而且entry中的value是不允许为nul的。好了,我们对hashtable整体上了解了后,下面开始详细分析hashtable中的源码。

        首先我们看看hashtable都有哪些关键属性:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

private transient int count;//记录hashtable中有多少entry实体  

//阈值,用于判断是否需要调整hashtable的容量(threshold = 容量*加载因子)  

private int threshold;  

private float loadfactor; // 加载因子  

private transient int modcount = 0; // hashtable被改变的次数,用于fail-fast  

// 序列版本号  

private static final long serialversionuid = 1421746759512286392l;  

//最大的门限阈值,不能超过这个  

static final int alternative_hashing_threshold_default = integer.max_value;  

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

//参数为数组容量和加载因子的构造方法  

public hashtable(int initialcapacity, float loadfactor) {  

    if (initialcapacity < 0)  

        throw new illegalargumentexception("illegal capacity: "+  

                                           initialcapacity);  

    if (loadfactor <= 0 || float.isnan(loadfactor))  

        throw new illegalargumentexception("illegal load: "+loadfactor);  

    if (initialcapacity==0)  

        initialcapacity = 1;  

    this.loadfactor = loadfactor;  

    table = new entry[initialcapacity]; //初始化数组  

    //初始化门限 = 容量 * 加载因子  

    threshold = (int)math.min(initialcapacity * loadfactor, max_array_size + 1);  

    inithashseedasneeded(initialcapacity);  

//参数为初始容量的构造方法  

public hashtable(int initialcapacity) {  

    this(initialcapacity, 0.75f); //我们可以看出,默认加载因子为0.75  

}   

//默认构造方法  

public hashtable() { //可以看出,默认容量为11,加载因子为0.75  

    this(11, 0.75f);  

//包含“子map”的构造函数  

public hashtable(map<? extends k, ? extends v> t) {  

    this(math.max(2*t.size(), 11), 0.75f);//先比较容量,如果map的2倍容量大于11,则使用新的容量  

    putall(t);  

        我们可以看到,如果我们不指定数组容量和加载因子,hashtable会自动初始化容量为11,加载因子为0.75。加载因子和hashmap是相同的。

        和hashmap的分析一样,hashtable的存取部分重点分析put和get方法,其他的方法我放到代码中分析。首先看看hashtable是如何存储数据的:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

public synchronized v put(k key, v value) {  

    //确保value不为空  

    if (value == null) {  

        throw new nullpointerexception();  

    entry tab[] = table;  

    int hash = hash(key); //计算哈希值  

    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)) { //如果对应的key已经存在  

            v old = e.value;  

            e.value = value; //替换掉原来的value  

            return old;  

        }  

    //否则新添加一个entry  

    modcount++;  

    if (count >= threshold) { //判断数组中的entry数量是否已经达到阈值  

        rehash(); //如果达到了,扩容  

        tab = table;  

        hash = hash(key); //重新计算哈希值  

        index = (hash & 0x7fffffff) % tab.length; //重新计算在新的数组中的索引  

    //创建一个新的entry  

    entry<k,v> e = tab[index];  

    //存到对应的位置,并将其next置为原来该位置的entry,这样就与原来的连上了  

    tab[index] = new entry<>(hash, key, value, e);  

    count++;  

    return null;  

              然后便开始往数组中存数据了,如果当前的key已经在里面了,那么直接替换原来旧的value,如果不存在,先判断数组中的entry数量有没有达到门限值,达到了就要调用rehash方法进行扩容,然后重新计算当前key在新的数组中的索引值,然后在该位置添加进去即可。下面我们看一下rehash方法:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

private static final int max_array_size = integer.max_value - 8;  

protected void rehash() {  

    int oldcapacity = table.length;  

    entry<k,v>[] oldmap = table; //保存旧数组  

    int newcapacity = (oldcapacity << 1) + 1; //新数组容量 = 2 * 旧容量 + 1  

    if (newcapacity - max_array_size > 0) {  

        if (oldcapacity == max_array_size)   

            return;  

        newcapacity = max_array_size; //不能超出最大值  

    entry<k,v>[] newmap = new entry[newcapacity];  

    threshold = (int)math.min(newcapacity * loadfactor, max_array_size + 1);  

    boolean rehash = inithashseedasneeded(newcapacity);  

    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;  

            if (rehash) {  

                e.hash = hash(e.key);  

            }  

            int index = (e.hash & 0x7fffffff) % newcapacity;//重新计算在新的数组中的索引  

            //第一次newmap[index]为空,后面每次的nex都是当前的entry,这样才能连上  

            e.next = newmap[index];  

            newmap[index] = e;//然后将该entry放到当前位置  

        到这里put方法就分析完了,还有个putall方法,是将整个map加到当前hashtable中,内部也是遍历每个entry,然后调用上面的put方法而已,简单看一下吧:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

public synchronized void putall(map<? extends k, ? extends v> t) {  

    for (map.entry<? extends k, ? extends v> e : t.entryset())  

        put(e.getkey(), e.getvalue());  

        到这里,是不是感觉hashtable其实很简单,比hashmap简单多了。下面来看看get方法,也很简单,我觉得已经不用再分析了……

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

public synchronized v get(object key) {  

    int hash = hash(key); //哈希值  

    int index = (hash & 0x7fffffff) % tab.length; //索引值  

        if ((e.hash == hash) && e.key.equals(key)) {  

            return e.value; //拿到value  

        上面分析完了存取方法,剩下来的其他方法我放到代码里分析了,也很简单:

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

//返回数组中entry数  

public synchronized int size() {  

    return count;  

//判断是否为空  

public synchronized boolean isempty() {  

    return count == 0;  

//返回所有key的枚举对象  

public synchronized enumeration<k> keys() {  

    return this.<k>getenumeration(keys);  

//返回所有value的枚举对象  

public synchronized enumeration<v> elements() {  

    return this.<v>getenumeration(values);  

//内部私有方法,返回枚举对象  

private <t> enumeration<t> getenumeration(int type) {  

    if (count == 0) {  

        return collections.emptyenumeration();  

    } else {  

        return new enumerator<>(type, false); //new一个enumeration对象,见下面:  

// types of enumerations/iterations  

private static final int keys = 0;  

private static final int values = 1;  

private static final int entries = 2;  

//私有内部类,实现了enumeration接口和iterator接口  

private class enumerator<t> implements enumeration<t>, iterator<t> {  

    entry[] table = hashtable.this.table;  

    int index = table.length;  

    entry<k,v> entry = null;  

    entry<k,v> lastreturned = null;  

    int type;  

    //该字段用来决定是使用iterator还是enumeration  

    boolean iterator; //false表示使用enumeration  

    //fail-fast  

    protected int expectedmodcount = modcount;  

    enumerator(int type, boolean iterator) {  

        this.type = type;  

        this.iterator = iterator;  

    public boolean hasmoreelements() { //判断是否含有下一个元素  

        entry<k,v> e = entry;  

        int i = index;  

        entry[] t = table;  

        /* use locals for faster loop iteration */  

        while (e == null && i > 0) {  

            e = t[--i];  

        entry = e;  

        index = i;  

        return e != null;  

    public t nextelement() { //获得下一个元素  

        entry<k,v> et = entry;  

        while (et == null && i > 0) {  

            et = t[--i];  

        entry = et;  

        if (et != null) {  

            entry<k,v> e = lastreturned = entry;  

            entry = e.next;  

            //根据传进来的关键字决定返回什么  

            return type == keys ? (t)e.key : (type == values ? (t)e.value : (t)e);  

        throw new nosuchelementexception("hashtable enumerator");  

    // iterator methods  

    public boolean hasnext() {  

        return hasmoreelements();  

    public t next() {  

        if (modcount != expectedmodcount)  

            throw new concurrentmodificationexception();  

        return nextelement();  

    public void remove() {  

        if (!iterator)  

            throw new unsupportedoperationexception();  

        if (lastreturned == null)  

            throw new illegalstateexception("hashtable enumerator");  

        synchronized(hashtable.this) { //保证了线程安全  

            entry[] tab = hashtable.this.table;  

            int index = (lastreturned.hash & 0x7fffffff) % tab.length;  

            for (entry<k,v> e = tab[index], prev = null; e != null;  

                 prev = e, e = e.next) {  

                if (e == lastreturned) {  

                    modcount++;  

                    expectedmodcount++;  

                    if (prev == null)  

                        tab[index] = e.next;  

                    else  

                        prev.next = e.next;  

                    count--;  

                    lastreturned = null;  

                    return;  

                }  

//判断hashtable中是否包含value值  

public synchronized boolean contains(object value) {  

    if (value == null) { //value不能为空  

    //从后向前遍历table数组中的元素(entry)  

    for (int i = tab.length ; i-- > 0 ;) {  

        for (entry<k,v> e = tab[i] ; e != null ; e = e.next) {  

            if (e.value.equals(value)) {  

                return true;  

    return false;  

public boolean containsvalue(object value) {  

    return contains(value);  

//判断hashtable中是否包含key  

public synchronized boolean containskey(object key) {  

    int hash = hash(key);  

    int index = (hash & 0x7fffffff) % tab.length;  

            return true;  

//删除hashtable中键为key的entry,并返回value  

public synchronized v remove(object key) {  

    //找到key对应的entry,然后在链表中找到要删除的节点,删除之。  

    for (entry<k,v> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {  

            modcount++;  

            if (prev != null) {  

                prev.next = e.next;  

            } else {  

                tab[index] = e.next;  

            count--;  

            v oldvalue = e.value;  

            e.value = null;  

            return oldvalue;  

//清空hashtable  

public synchronized void clear() {  

    for (int index = tab.length; --index >= 0; )  

        tab[index] = null; //将hashtable中数组值全部设置为null  

    count = 0;  

//克隆一个hashtable,并以object的形式返回  

public synchronized object clone() {  

    try {  

        hashtable<k,v> t = (hashtable<k,v>) super.clone();  

        t.table = new entry[table.length];  

        for (int i = table.length ; i-- > 0 ; ) {  

            t.table[i] = (table[i] != null)  

                ? (entry<k,v>) table[i].clone() : null;  

        t.keyset = null;  

        t.entryset = null;  

        t.values = null;  

        t.modcount = 0;  

        return t;  

    } catch (clonenotsupportedexception e) {  

        // this shouldn't happen, since we are cloneable  

        throw new internalerror();  

//重写tostring方法:{, ,}  

public synchronized string tostring() {  

    int max = size() - 1;  

    if (max == -1)  

        return "{}";  

    stringbuilder sb = new stringbuilder();  

    iterator<map.entry<k,v>> it = entryset().iterator();  

    sb.append('{');  

    for (int i = 0; ; i++) {  

        map.entry<k,v> e = it.next();  

        k key = e.getkey();  

        v value = e.getvalue();  

        sb.append(key   == this ? "(this map)" : key.tostring());  

        sb.append('=');  

        sb.append(value == this ? "(this map)" : value.tostring());  

        if (i == max)  

            return sb.append('}').tostring();  

        sb.append(", ");  

}     

// hashtable的“key的集合”。它是一个set,意味着没有重复元素  

private transient volatile set<k> keyset = null;  

// hashtable的“key-value的集合”。它是一个set,意味着没有重复元素  

private transient volatile set<map.entry<k,v>> entryset = null;  

// hashtable的“value的集合”。它是一个collection,意味着可以有重复元素  

private transient volatile collection<v> values = null;  

//返回一个被synchronizedset封装后的keyset对象  

//synchronizedset封装的目的是对keyset的所有方法都添加synchronized,实现多线程同步  

public set<k> keyset() {  

    if (keyset == null)  

        keyset = collections.synchronizedset(new keyset(), this);  

    return keyset;  

private class keyset extends abstractset<k> {  

    public iterator<k> iterator() {  

        return getiterator(keys); //返回一个迭代器,装有hashtable的信息  

        //从这里也可以看出,获取到了key的set集合后,要想取数据,只能通过迭代器  

    public int size() {  

        return count;  

    public boolean contains(object o) {  

        return containskey(o);  

    public boolean remove(object o) {  

        return hashtable.this.remove(o) != null;  

    public void clear() {  

        hashtable.this.clear();  

// 获取hashtable的迭代器  

// 若hashtable的实际大小为0,则返回“空迭代器”对象;  

// 否则,返回正常的enumerator的对象。(由上面代码可知,enumerator实现了迭代器和枚举两个接口)  

private <t> iterator<t> getiterator(int type) {  

        return collections.emptyiterator();  

        return new enumerator<>(type, true);  

//返回一个被synchronizedset封装后的entryset对象  

public set<map.entry<k,v>> entryset() {  

    if (entryset==null)  

        entryset = collections.synchronizedset(new entryset(), this);  

    return entryset;  

//跟keyset类似  

private class entryset extends abstractset<map.entry<k,v>> {  

    public iterator<map.entry<k,v>> iterator() {  

        return getiterator(entries);  

    public boolean add(map.entry<k,v> o) {  

        return super.add(o);  

    // 查找entryset中是否包含object(o)  

    // 首先,在table中找到o对应的entry(entry是一个单向链表)  

    // 然后,查找entry链表中是否存在object  

        map.entry entry = (map.entry)o;  

        object key = entry.getkey();  

        entry[] tab = table;  

        int hash = hash(key);  

        int index = (hash & 0x7fffffff) % tab.length;  

        for (entry e = tab[index]; e != null; e = e.next)  

            if (e.hash==hash && e.equals(entry))  

        return false;  

    // 删除元素object(o)  

    // 然后,删除链表中的元素object  

        map.entry<k,v> entry = (map.entry<k,v>) o;  

        k key = entry.getkey();  

        for (entry<k,v> e = tab[index], prev = null; e != null;  

             prev = e, e = e.next) {  

            if (e.hash==hash && e.equals(entry)) {  

                modcount++;  

                if (prev != null)  

                    prev.next = e.next;  

                else  

                    tab[index] = e.next;  

                count--;  

                e.value = null;  

// 返回一个被synchronizedcollection封装后的valuecollection对象  

// synchronizedcollection封装的目的是对valuecollection的所有方法都添加synchronized,实现多线程同步  

public collection<v> values() {  

    if (values==null)  

        values = collections.synchronizedcollection(new valuecollection(),  

                                                    this);  

    return values;  

private class valuecollection extends abstractcollection<v> {  

    public iterator<v> iterator() {  

        return getiterator(values); //同上  

        return containsvalue(o);  

//重写equals()方法  

// 若两个hashtable的所有key-value键值对都相等,则判断它们两个相等  

public synchronized boolean equals(object o) {  

    if (o == this)  

        return true;  

    if (!(o instanceof map))  

    map<k,v> t = (map<k,v>) o;  

    if (t.size() != size())  

        iterator<map.entry<k,v>> i = entryset().iterator();  

        while (i.hasnext()) {  

            map.entry<k,v> e = i.next();  

            k key = e.getkey();  

            v value = e.getvalue();  

            if (value == null) {  

                if (!(t.get(key)==null && t.containskey(key)))  

                    return false;  

                if (!value.equals(t.get(key)))  

    } catch (classcastexception unused)   {  

    } catch (nullpointerexception unused) {  

    return true;  

//计算哈希值  

//若hashtable的实际大小为0或者加载因子<0,则返回0  

//否则返回“hashtable中的每个entry的key和value的异或值的总和”  

public synchronized int hashcode() {  

    int h = 0;  

    if (count == 0 || loadfactor < 0)  

        return h;  // returns zero  

    loadfactor = -loadfactor;  // mark hashcode computation in progress  

    entry[] tab = table;  

    for (entry<k,v> entry : tab)  

        while (entry != null) {  

            h += entry.hashcode();  

            entry = entry.next;  

    loadfactor = -loadfactor;  // mark hashcode computation complete  

    return h;  

// java.io.serializable的写入函数  

// 将hashtable的“总的容量,实际容量,所有的entry”都写入到输出流中  

private void writeobject(java.io.objectoutputstream s)  

        throws ioexception {  

    entry<k, v> entrystack = null;  

    synchronized (this) {  

        // write out the length, threshold, loadfactor  

        s.defaultwriteobject();  

        // write out length, count of elements  

        s.writeint(table.length);  

        s.writeint(count);  

        // stack copies of the entries in the table  

        for (int index = 0; index < table.length; index++) {  

            entry<k,v> entry = table[index];  

            while (entry != null) {  

                entrystack =  

                    new entry<>(0, entry.key, entry.value, entrystack);  

                entry = entry.next;  

    // write out the key/value objects from the stacked entries  

    while (entrystack != null) {  

        s.writeobject(entrystack.key);  

        s.writeobject(entrystack.value);  

        entrystack = entrystack.next;  

// java.io.serializable的读取函数:根据写入方式读出  

// 将hashtable的“总的容量,实际容量,所有的entry”依次读出  

private void readobject(java.io.objectinputstream s)  

     throws ioexception, classnotfoundexception  

{  

    // read in the length, threshold, and loadfactor  

    s.defaultreadobject();  

    // read the original length of the array and number of elements  

    int origlength = s.readint();  

    int elements = s.readint();  

    // compute new size with a bit of room 5% to grow but  

    // no larger than the original size.  make the length  

    // odd if it's large enough, this helps distribute the entries.  

    // guard against the length ending up zero, that's not valid.  

    int length = (int)(elements * loadfactor) + (elements / 20) + 3;  

    if (length > elements && (length & 1) == 0)  

        length--;  

    if (origlength > 0 && length > origlength)  

        length = origlength;  

    entry<k,v>[] newtable = new entry[length];  

    threshold = (int) math.min(length * loadfactor, max_array_size + 1);  

    inithashseedasneeded(length);  

    // read the number of elements and then all the key/value objects  

    for (; elements > 0; elements--) {  

        k key = (k)s.readobject();  

        v value = (v)s.readobject();  

        // synch could be eliminated for performance  

        reconstitutionput(newtable, key, value);  

    this.table = newtable;  

private void reconstitutionput(entry<k,v>[] tab, k key, v value)  

    throws streamcorruptedexception  

        throw new java.io.streamcorruptedexception();  

    // makes sure the key is not already in the hashtable.  

    // this should not happen in deserialized version.  

            throw new java.io.streamcorruptedexception();  

    // creates the new entry.  

        hashtable的遍历方式比较简单,一般分两步:

        1. 获得entry或key或value的集合;

        2. 通过iterator迭代器或者enumeration遍历此集合。

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

// 假设table是hashtable对象  

// table中的key是string类型,value是integer类型  

integer value = null;  

iterator iter = table.entryset().iterator();  

while(iter.hasnext()) {  

    map.entry entry = (map.entry)iter.next();  

    // 获取key  

    key = (string)entry.getkey();  

    // 获取value  

    value = (integer)entry.getvalue();  

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

string key = null;  

iterator iter = table.keyset().iterator();  

while (iter.hasnext()) {  

    key = (string)iter.next();  

    // 根据key,获取value  

    value = (integer)table.get(key);  

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

collection c = table.values();  

iterator iter= c.iterator();  

    value = (integer)iter.next();  

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

enumeration enu = table.keys();  

while(enu.hasmoreelements()) {  

    system.out.println(enu.nextelement());  

java集合框架09——HashTable和源码分析 1.HashTable简介 2. HashTable的数据结构 3.HashTable源码分析(基于JDK1.7) 4.HashTable的遍历方式

enumeration enu = table.elements();  

        hashtable的遍历就介绍到这吧,至此,hashtable的源码就讨论完了,如有错误之处,欢迎留言指正~

转载:http://blog.csdn.net/eson_15/article/details/51208166