JAVA:hashtable常用方法和源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dian1pei2xiao3/article/details/84842013
 public  static void main(String[] args) {

        Hashtable<String,Integer> hashtable=new Hashtable<String, Integer>();
        
        /**hashtable底层数据结构:数组+链表
         * 不能存储Null值
         * 不能保证插入有序
         * 线程安全
         * 增加元素,数组扩容方式为2倍+1的方式,初始容量为11
         *  继承Dictionary<K,V>类,提供了特有的遍历方式(枚举遍历Enumeration:)其中有
         *  boolean hasMoreElements()和E nextElement()方法,在hashtable中调用使用elements()方法调用
         *  同时实现implements Map<K,V>, Cloneable, java.io.Serializable接口
         */
         hashtable.put("ls",18);//插入元素
         hashtable.put("zs",19);
         //put源码分析:
        /**初始容量和加载因子
         *  public Hashtable() {
         *         this(11, 0.75f);
         *     }
         *  public synchronized V put(K key, V value) {
         *         if (value == null) {//           1.说明value值不能为null
         *             throw new NullPointerException();
         *         }
         *         Entry<?,?> tab[] = table;
         *         int hash = key.hashCode();//计算哈希值,此处说明value值不能为null,否则会出现空指针异常
         *         int index = (hash & 0x7FFFFFFF) % tab.length;//计算位置
         *         Entry<K , V> entry = (Entry<K,V>)tab[index];
         *         for(; entry != null ; entry = entry.next) {//遍历查找是否插入的新元素和旧元素hash值和key值相等,
         *          如果相等用新的value替换旧的value,并返回旧的value,否则跳出for循环。直接插入元素
         *         
         *             if ((entry.hash == hash) && entry.key.equals(key)) {
         *                 V old = entry.value;
         *                 entry.value = value;
         *                 return old;
         *             }
         *         }
         *
         *         addEntry(hash, key, value, index);//存在扩容机制
         *         return null;
         *     }
         *     //添加元素addEntry
         *       private void addEntry(int hash, K key, V value, int index) {
         *         modCount++;
         *         Entry<?,?> tab[] = table;
         *         if (count >= threshold) {
         *         如果大于阈值需要重哈希,
         *             rehash();
         *
         *             tab = table;
         *             hash = key.hashCode();
         *             index = (hash & 0x7FFFFFFF) % tab.length;//与hashmap的计算哈希位置不同
         *         }
         *         Entry<K , V> e = (Entry<K,V>) tab[index];
         *         tab[index] = new Entry<>(hash, key, value, e);
         *         count++;
         *     }
         *     重哈希
         *  protected void rehash() {
         *         int oldCapacity = table.length;
         *         Entry<?,?>[] 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<?,?>[] newMap = new Entry<?,?>[newCapacity];
         *
         *         modCount++;
         *         //重新计算阈值:新的容量*加载因子和最大值+1中最小的值,阈值的作用显然实在添加元素是判断是否扩容数组发挥作用
         *         threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
         *         table = newMap;
         *          //将旧的元素通过for循环放入新的数组
         *         for (int i = oldCapacity ; i-- > 0 ;) {
         *             for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
         *                 Entry<K,V> e = old;
         *                 old = old.next;
         *
         *                 int index = (e.hash & 0x7FFFFFFF) % newCapacity;
         *                 e.next = (Entry<K,V>)newMap[index];
         *                 newMap[index] = e;
         *             }
         *         }
         *     }
         *     
         *
         */
         hashtable.remove("ls");
        /**
         * 删除元素:
         * 1.计算哈希值
         * 2.通过哈希值找位置
         * 3.通过位置找节点,遍历整个链表,如果存在,根据链表的删除元素的方法删除即可,
         * 最后需要将value值赋值为null,避免内存泄漏
         * 
         * 
         *  public synchronized V remove(Object key) {
         *         Entry<?,?> tab[] = table;
         *         int hash = key.hashCode();
         *         int index = (hash & 0x7FFFFFFF) % tab.length;
         *         Entry<K , V> e = (Entry<K,V>)tab[index];
         *         for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
         *             if ((e.hash == hash) && e.key.equals(key)) {
         *                 modCount++;
         *                 if (prev != null) {
         *                     prev.next = e.next;
         *                 } else {
         *                     tab[index] = e.next;
         *                 }
         *                 count--;
         *                 V oldValue = e.value;
         *                 e.value = null;
         *                 return oldValue;
         *             }
         *         }
         *         return null;
         *     }
         *
         */
        Integer ls = hashtable.get("ls");
        /**
         * 通过键获取元素,也是:
         * 1.计算哈希值
         * 2.通过哈希函数计算位置
         * 3.遍历查找,返回value
         *  public synchronized V get(Object key) {
         *         Entry<?,?> tab[] = table;
         *         int hash = key.hashCode();
         *         int index = (hash & 0x7FFFFFFF) % tab.length;
         *         for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
         *             if ((e.hash == hash) && e.key.equals(key)) {
         *                 return (V)e.value;
         *             }
         *         }
         *         return null;
         *     }
         *
         */
        hashtable.contains("ls");
        /**
         * 
         *  public synchronized boolean contains(Object value) {
         *         if (value == null) {
         *             throw new NullPointerException();//value值不能为null
         *         }
         *         Entry<?,?> tab[] = table;
         *         for (int i = tab.length ; i-- > 0 ;) {//倒着遍历数组
         *             for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {//遍历每个数组每个位置的链表
         *                 if (e.value.equals(value)) {
         *                     return true;
         *                 }
         *             }
         *         }
         *         return false;
         *     }
         */
        


        /**
         * 
         * 遍历方式有四种,如下
         */
        //使用枚举的方法遍历
        Enumeration<Integer> elements = hashtable.elements();
        while (elements.hasMoreElements()){
            Integer integer = elements.nextElement();
            System.out.println(integer);
        }
        //节点的方式遍历
        Set<Map.Entry<String, Integer>> entries = hashtable.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> next = iterator.next();
            System.out.println(next.getValue());
        }
        //key遍历
        Set<String> strings = hashtable.keySet();
        Iterator<String> iterator1 = strings.iterator();
        while (iterator1.hasNext()){
            String next = iterator1.next();
            System.out.println(next);
        }
        //value值遍历
        Collection<Integer> values = hashtable.values();
        Iterator<Integer> iterator2 = values.iterator();
        while (iterator2.hasNext()){
            Integer next = iterator2.next();
            System.out.println(next);
        }
       

    }

猜你喜欢

转载自blog.csdn.net/Dian1pei2xiao3/article/details/84842013