A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 张扬123 于 2012-7-29 00:09 编辑
  1. import java.util.*;
  2. class PrintData
  3. {
  4.         static void print(Enumeration e){
  5.                 while (e.hasMoreElements())
  6.                 {
  7.                         System.out.println(
  8.                                 e.nextElement().toString()
  9.                                 );
  10.                 }
  11.         }
  12. };
  13. class Mouse
  14. {
  15.         private int i;
  16.         public Mouse(int i)
  17.         {
  18.                 this.i=i;
  19.         }
  20.         public String toString(){
  21.                 return "Mouse:"+ i;
  22.         }
  23. };
  24. class Hamster
  25. {
  26.         private int i;
  27.         public Hamster(int i){
  28.                 this.i=i;
  29.         }
  30.         public String toString(){
  31.                 return "Hamster:"+Integer.toString(this.i);
  32.         }
  33. };
  34. public class  Enumeration2
  35. {
  36.         public static void main(String[] args)
  37.         {
  38.                 System.out.println("Hello World!");
  39.                 Vector v =new Vector();
  40.                 for (int i =0;i<5 ; i++)
  41.                 {
  42.                         v.addElement(new Mouse(i));
  43.                 }
  44.             Hashtable h=new Hashtable();
  45.                 for (int i=0;i<4 ;i++ )
  46.                 {
  47.                         h.put(Integer.toString(i),new Hamster(i));
  48.                 }
  49.                 System.out.println("vector");
  50.                 PrintData.print(v.elements());
  51.                 System.out.println("hashtable");
  52.                 PrintData.print(h.elements());
  53.         }
  54. }
复制代码
如上代码在执行时执行的结果为什么使用vector的elements()方法得到的Enumeration类打印的结果是0,1,2,3,4;而hashtable的elements()方式得到的Enumeration类打印结果是3,2,1,0。求解释,谢谢。

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

3 个回复

倒序浏览
hashtable,底层是个table,hashtable吧table的index给hash了一下。
  public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        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)) {
                V old = e.value;
                e.value = value;
                return old;
            }
        }

        modCount++;
        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
        }

        // Creates the new entry.
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<K,V>(hash, key, value, e);
        count++;
        return null;
    }

存完了之后,里面的table可能是这样的(在我这里这次运行)
[null, null, null, null, 0=Hamster:0, 1=Hamster:1, 2=Hamster:2, 3=Hamster:3, null, null, null]
-------------------------------------------------------
在这段代码里
04.        static void print(Enumeration e){
05.                while (e.hasMoreElements())
06.                {
07.                        System.out.println(
08.                                e.nextElement().toString()
09.                                );
10.                }
11.        }
-----迭代用到的两个方法hasMoreElements()和nextElement()的代码如下:
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;
            int i = index;
            Entry[] t = table;
            /* Use locals for faster loop iteration */
            while (et == null && i > 0) {
                et = t[--i];
            }
            entry = et;
            index = i;
            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");
        }
从这两个方法的实现里就应该能看到原因了,简单说就是,存的时候是随机存的,取的时候是倒着取的。
----
在我这里存的是按顺序存的,我感觉这可能是种偶然吧,毕竟hash应该是无序的。所以,取出来的是倒序也就是一种偶然,在更多的情况下,取出来的应该是无序的。

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
黑马高明辉 发表于 2012-7-26 04:46
hashtable,底层是个table,hashtable吧table的index给hash了一下。
  public synchronized V put(K key, V ...

好的。我再多试试。
回复 使用道具 举报
这个其实储存的方法就是不一样的,像栈,和堆。Stack类和Queue()接口下面实现的子类,
一种是杯子:stack类,先进后出。类似于栈内存
一种是管子:Queue接口,先进先出。类似于堆内存。
而HashSet本身是由哈希值确定排列顺序的,出现有序的情况可以理解为偶然,或是这些数字的哈希值是有序的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马