栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java集合类史上最细讲解 - HashTable,Properties篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java集合类史上最细讲解 - HashTable,Properties篇

java集合类史上最细讲解 - HashTable,Properties篇
  • 1.基本介绍
  • 2.HashTable底层
  • 3.HashTable扩容机制
  • 4.HashMap和HashTable的对比
  • 5.Properties
  • 6.集合选型规则

1.基本介绍
  • HashTable的键和值都不能为空,否则会抛出一个异常
  • 使用方法基本与HashMap一致
  • HashTable是线程安全的,HashMap是线程不安全的

2.HashTable底层

先上代码:

Hashtable hashtable = new Hashtable();
hashtable.put("john",100);
hashtable.put("tom",250);
hashtable.put("tom",1314);
System.out.println(hashtable);
------------------------
输出:
{tom=1314, john=100}

先进入put方法,可以看到在put方法最前面先判断了value是否为空,如果为空直接抛出一个异常

if (value == null) {
    throw new NullPointerException();
}

同样的,HashTable也存在替换机制和扩容机制!


3.HashTable扩容机制

HashTable拥有自己的扩容机制,这不同于HashSet和HashMap

首先,我们要明白,在HashTable添加键值对时,真正起到添加作用的是如下方法:

addEntry(hash, key, value, index);

我们来看一下他的真面目:

private void addEntry(int hash, K key, V value, int index) {
    Entry tab[] = table;
    if (count >= threshold) {
        // Rehash the table if the threshold is exceeded
        rehash();

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

    // Creates the new entry.
    @SuppressWarnings("unchecked")
    Entry e = (Entry) tab[index];
    tab[index] = new Entry<>(hash, key, value, e);
    count++;
    modCount++;
}

当添加的元素数量大于临界值时,执行rehash方法(这个方法就是真正的扩容方法)

if (count >= threshold) {
    // Rehash the table if the threshold is exceeded
    rehash();
    tab = table;
    hash = key.hashCode();
    index = (hash & 0x7FFFFFFF) % tab.length;
}

继续追进去到rehash方法:

protected void rehash() {
    int oldCapacity = table.length;
    Entry[] oldMap = table;

    // overflow-conscious code
    int newCapacity = (oldCapacity << 1) + 1;
    if (newCapacity - MAX_ARRAY_SIZE > 0) {
        if (oldCapacity == MAX_ARRAY_SIZE)
            // Keep running with MAX_ARRAY_SIZE buckets
            return;
        newCapacity = MAX_ARRAY_SIZE;
    }
    Entry[] newMap = new Entry[newCapacity];

    modCount++;
    threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    table = newMap;

    for (int i = oldCapacity ; i-- > 0 ;) {
        for (Entry old = (Entry)oldMap[i] ; old != null ; ) {
            Entry e = old;
            old = old.next;

            int index = (e.hash & 0x7FFFFFFF) % newCapacity;
            e.next = (Entry)newMap[index];
            newMap[index] = e;
        }
    }
}

不要慌,我们来分析一下这个扩容方法

首先,拿到老的容量:

int oldCapacity = table.length;

新的容量为老的容量 * 2 + 1:

int newCapacity = (oldCapacity << 1) + 1;

继续往下,到达真正扩容的代码:

Entry[] newMap = new Entry[newCapacity];

4.HashMap和HashTable的对比


5.Properties

Properties继承了HashTable

一般用于可操作的配置文件编写

使用实例:

import java.util.Properties;


public class PropertiesText {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Properties properties = new Properties();
        // 增加
        properties.put("john",521);
        properties.put("tom",1314);
        properties.put("tom",100);
        System.out.println(properties);
        // 通过key获取值
        System.out.println(properties.get("tom"));
        // 删除
        properties.remove("tom");
        System.out.println(properties);
    }
}
------------------------------
输出:
{tom=100, john=521}
100
{john=521}

6.集合选型规则

存储一组对象:Collection

  • 允许重复,增删多选LinkedList,改查多选ArrayList
  • 不允许重复,无序选HashSet,排序选TreeSet,插入和取出顺序一致选择LinkedHashSet

存储键值对:Map

  • 键无序:HashMap
  • 键排序:TreeMap
  • 键插入和取出顺序一致:LinkedHashMap
  • 读取文件:Properties
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027356.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号