HashMap与Hashtable的分析

HashTable与HashMap概念

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。另外,HashMap是非线程安全的,也就是说在多线程的环境下,可能会存在问题,而Hashtable是线程安全的。

我们先来说HashTable  它的底层是用数据+链表实现的,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低。

HashTable

1、基本方法实现

        //创建一个HashTable实例
        Hashtable<Integer, Object> ht=new Hashtable<>();

        //key键是唯一的、value可以重复
        ht.put(1, "A");
        ht.put(2, "B");
        ht.put(3, "C");
        ht.put(4, "D");

        if(ht.contains("C")) {
            //判断哈希表表中是否包含特定律、返回值是true或者false
        }

        //移除一个key或者值
        ht.remove("C");

        //移除所有元素
        ht.clear();

2、排序方式

 Hashtable ht = new Hashtable();
  ht.Add("a", 5);
  ht.Add("b", 22);
  ht.Add("c", 16);

2.1   使用 ArrayList 数组排序

ArrayList al = new ArrayList(ht.Keys);
  al.Sort();
  1)按键升序输出
  for(int i = 0; i < al.Count; i++)
        Response.Write("键:" + al[i] + " 的值为:" + ht[al[i]].ToString() + "<br />");
  输出结果:
  键:a 的值为:5
  键:b 的值为:22
  键:c 的值为:16

  2)按键降序输出
  for(int i = al.Count - 1; i >= 0; i--)
        Response.Write("键:" + al[i] + " 的值为:" + ht[al[i]].ToString() + "<br />");
  输出结果:
  键:c 的值为:16
  键:b 的值为:22
  键:a 的值为:5

2.2  使用 Array 数组按值排序

string[] arrKey = new string[ht.Count];//暂存 Hashtable 的键
  int[] arrValue = new int[ht.Count];//暂存 Hashtable 的值
  ht.Keys.CopyTo(arrKey, 0);
  ht.Values.CopyTo(arrValue, 0);
  Array.Sort(arrValue, arrKey);//按 HashTable 的值排序
  for(int i = 0; i < arrKey.Length; i++)
        Response.Write("键:" + arrKey[i].ToString() + " 的值为:" + arrValue[i].ToString() + "<br />");
  输出结果:
  键:a 的值为:5
  键:c 的值为:16
  键:b 的值为:22

2.3  使用 DataTable 按键或值排序

DataTable dt = new DataTable();
  dt.Columns.Add("htKey", typeof(string));
  dt.Columns.Add("htValue", typeof(int));
  IDictionaryEnumerator ide = ht.GetEnumerator();
  while (ide.MoveNext())
  {
        DataRow dr = dt.NewRow();
        dr["htKey"] = ide.Key.ToString();
        dr["htValue"] = ide.Value.ToString();
        dt.Rows.Add(dr);
  }
  DataView dv = dt.DefaultView;
  dv.Sort = "htValue Desc";//此处是按值降序排列
  DataTable dt1 = dv.ToTable();
  for (int i = 0; i < dt1.Rows.Count; i++)
        Response.Write("键:" + dt1.Rows[i]["htKey"].ToString() + " 的值为:" + dt1.Rows[i]["htValue"].ToString() + "<br/>");
  输出结果:
  键:b 的值为:22
  键:c 的值为:16
  键:a 的值为:5

3、增长因子

  • 初始size为11,扩容:newsize = olesize*2+1
  • 计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length

HashMap

1、map 键值对   json格式  根据你的键名来获取对应的值

Map<String,Object> m=new HashMap<>();
        m.put("zh", "中国");
        m.put("en", "英国");
        m.put("jp", "日本");
        m.put("mg", "美国");
        if(!m.containsKey("zh")) {
            m.put("zh", "大中国");
        }

        //排序    是按照值的第一个字母来   A-Z   排序
        System.out.println(m);

        //1、重复的key会有什么样子的问题
        //key相同则覆盖value值、以最后一个加入进去的值为真

        //2、如果值相同  而key不同 又会成为什么?
        //值相同、而键不同    则创建两个
        //键值对关系    只和键挂钩   而和值无关

2、map集合的遍历方式

Map<Integer,Object> m=new HashMap<>();
        //避免出现重复的值

        for(int i=0;i<10;i++) {
            if(!m.containsKey(i)) {
                m.put(i, "z"+i);
            }
        }

        System.out.println(m.get(0));

        for(Integer i:m.keySet()) {
            System.out.println(i);
        }

        for(Object o:m.values()) {
            System.out.println(o);
        }

2.1  HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。

for(Entry<Integer, Object>  emp:m.entrySet()) {
            System.out.println("key:"+emp.getKey()+"value:"+emp.getValue());
        }
//Entry输出
key:0value:z0
key:1value:z1
key:2value:z2
key:3value:z3
key:4value:z4
key:5value:z5
key:6value:z6
key:7value:z7
key:8value:z8
key:9value:z9

//普通输出
{0=z0, 1=z1, 2=z2, 3=z3, 4=z4, 5=z5, 6=z6, 7=z7, 8=z8, 9=z9}

3、  HashMap的初始值还要考虑加载因子

  • 哈希冲突:若干Key的哈希值按数组大小取模后,如果落在同一个数组下标上,将组成一条Entry链,对Key的查找需要遍历Entry链上的每个元素执行equals()比较。
  • 加载因子:为了降低哈希冲突的概率,默认当HashMap中的键值对达到数组大小的75%时,即会触发扩容。因此,如果预估容量是100,即需要设定100/0.75=134的数组大小。
  • 空间换时间:如果希望加快Key查找的时间,还可以进一步降低加载因子,加大初始大小,以降低哈希冲突的概率。

总结一下:

  1. HashMap和Hashtable都是用hash算法来决定其元素的存储,因此HashMap和Hashtable的hash表包含如下属性
  2. 容量(capacity):hash表中桶的数量
  3. 初始化容量(initial capacity):创建hash表时桶的数量,HashMap允许在构造器中指定初始化容量
  4. 尺寸(size):当前hash表中记录的数量
  5. 负载因子(load factor):负载因子等于“size/capacity”。负载因子为0,表示空的hash表,0.5表示半满的散列表,依此类推。轻负载的散列表具有冲突少、适宜插入与查询的特点(但是使用Iterator迭代元素时比较慢)
  6. 除此之外,hash表里还有一个“负载极限”,“负载极限”是一个0~1的数值,“负载极限”决定了hash表的最大填满程度。当hash表中的负载因子达到指定的“负载极限”时,hash表会自动成倍地增加容量(桶的数量),并将原有的对象重新分配,放入新的桶内,这称为rehashing。
  7. HashMap和Hashtable的构造器允许指定一个负载极限,HashMap和Hashtable默认的“负载极限”为0.75,这表明当该hash表的3/4已经被填满时,hash表会发生rehashing。

原文地址:https://www.cnblogs.com/wshemin/p/10906861.html

时间: 2024-10-03 09:47:10

HashMap与Hashtable的分析的相关文章

从Java源码的角度来分析HashMap与HashTable的区别

由于HashMap与HashTable都是用来存储Key-Value的键值对,所以经常拿来对比二者的区别,下面就从源码的角度来分析一下HashMap与HashTable的区别, 首先介绍一下两者的区别,然后再从源码分析. HahMap与HahTable两者主要区别: 1.继承的父类不同 <span style="font-size:18px;">public class HashMap<K, V> extends AbstractMap<K, V>

[源码解析]HashMap和HashTable的区别(源码分析解读)

前言: 又是一个大好的周末, 可惜今天起来有点晚, 扒开HashMap和HashTable, 看看他们到底有什么区别吧. 先来一段比较拗口的定义: Hashtable 的实例有两个参数影响其性能:初始容量 和 加载因子.容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量.注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索.加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度.初始容量和加载因子这两个参数只是对该实现的提示.

HashMap与HashTable源码学习及效率比较分析

一.个人学习后的见解: 首先表明学习源码后的个人见解,后续一次依次进行分析: 1.线程安全:HashMap是非线程安全的,HashTable是线程安全的(HashTable中使用了synchronized关键字进行控制),HashMap对应的线程安全的有concurrentHashMap,但如果不用concurrentHashMap的话,也可以只用Collections.synchronizedMap(Map)进行转换. 2.key值为null时的不同处理方式:HashMap允许key值为nul

HashMap和Hashtable的区别 源码分析

一:以前只知道HashMap和HashTable区别,死记硬背的记住HashMap 允许key value为空 而Hashtable 不允许为空 HashMap线程是非线程安全的,而Hashtable是安全的. 二.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable public class HashM

ArrayList,Vector,HashMap,HashSet,HashTable之间的区别与联系

看上面的框架图,先抓住它的主干,即Collection和Map. 1 Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性. Collection包含了List和Set两大分支. (01) List是一个有序的队列,每一个元素都有它的索引.第一个元素的索引值是0. List的实现类有LinkedList, ArrayList, Vector, Stack. (02) Set是一个不允许有重复元素的集合. Set的实现类有HastSet和TreeSet.HashSet

HashMap与HashTable联系与区别

HashMap与HashTable 1.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法. 2.hashTable同步的,而HashMap是非同步的,效率上比hashTable要高,HashMap不是线程安全的 ,HashTable是线程安全的一个Collection.3.hashMap允许空键值,而hashTable不允许. ashtable继承自Dictionary类,而HashMap是Map接口的一个实

[转]HashMap与HashTable的区别、HashMap与HashSet的关系

转自: http://blog.csdn.net/wl_ldy/article/details/5941770 HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable.可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别. 一:HashMap与HashTable的区别 1.HashTable的方法是同步 的,在方法的前面都有synchronized来同步,HashMap未经同步,所以

Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结

2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分期.美团点评等都在1.2--面的时候被问过无数次,都问吐了&_&,其他公司笔试的时候,但凡有Java的题,都有集合相关考点,尤其hash表--现在总结下. Java集合概述 HashMap介绍 HashMap源码学习 关于HashMap的几个经典问题 HashTable介绍和源码学习 Hash

深入源码剖析 HashSet、HashMap、HashTable

HashTable HashTable 是什么 public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable HashTable 是 Java 中哈希表的一种实现形式,它是 Dictionary 的子类,并且实现了 Map 接口. 注1: 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接