Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的
Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例。假设我们保存下面一组数据,第一列作为key, 第二列作为value。
{“one", 1}
{"two", 2}
{"three", 3}
{"four", 4}
写一个演示程序:
import java.util.Hashtable;
public class Main {
public static void main(String[] args) {
Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);
numbers.put("four", 4);
numbers.put("five", 5);
Integer n = numbers.get("two");
Integer nn = numbers.get("six");
if(n != null)
System.out.println(n);
System.out.println(nn);
}
}
Hashtable内部用一个Entry数组table,来保存所有的数据。
当我们插入一个新的Entry对象时,即用Hashtable的put(key, value)方法。
在put方法里:
计算key的hash值
计算index值,作为数组table的下标,即table[index]
哈希表中根据key的索引值index,创建了多个bucket,所有index值一样的Entry对象,构造成一个链接表存放在同一个bucket里。既然是一个链接表,根据数据结构知识,自然我们的Entry对象需要有一个指向下一个对象的指针,即Entry对象需要有这些属性:key,value,next。
如何构造hash函数?
hash值,如何生成?对于每个对象的hash值,要保证每一个hash值都不一样。
在Java SDK中, String的hashCode方法如下:
//hash的初始值为0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
index值,如何生成?这里要求保存的数据是均匀的分配在每一个bucket中,Hashtable源码中采用%操作(mod)使数据分布在编号为0~10的bucket中。
Hashtable中put方法的源码如下:
private int hash(Object k) {
// hashSeed will be zero if alternative hashing is disabled.
return hashSeed ^ k.hashCode();
}
public synchronized V put(K key, V value) {
... ...
int hash = hash(key);
int index = (hash & 0x7FFFFFFF) % tab.length;
... ...
}
这样数据存储到哈希表之后,当我们要查找或者说获取一个对象时候,采用同样的方式可以快速的找到我们需要的对象。
哈希表可以快速的找到一个元素。在有大量的数据的时候,比普通的顺序查找要快的多。
假设有10000条数据,如果采用顺序查找,最坏的情况下需要对比10000次能找到,最好的情况是1次。平均查找次数位(10000+1)/2,大约为5000次。
换一种方式,如果把10000条数据通过hash值索引分成10组,每一组有1000条数据,这样每一次只需要先确定是哪一组,然后在1000条数据里查找,这样最坏的情况是1000次, 最好的情况是1次。平均查找次数为(1000+1)/2 ,大约为500次。比上面的方法快了5倍。
我们常用的5种算法有顺序查找,二分法查找,二叉排序树查找,哈希表法查找,分块查找。Java的Hashtable即是用了哈希表法查找。
Java中哈希表(Hashtable)是如何实现的的更多相关文章
- C#中哈希表(HashTable)的用法详解以及和Dictionary比较
1. 哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对, ...
- 转 C#中哈希表(HashTable)的用法详解
看了一遍有关哈希表的文字,作者总结的真是不错 .收藏起来 1. 哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提 ...
- C#中哈希表(HashTable)的用法详解
描述: 哈希表存放 key.values ,key值可以用于快速调取用,values 对应object类型,也就是说所有类型. 实例: 1.HashTable存放学生的成绩 Hashtable ht1 ...
- java集合-哈希表HashTable
一.简介 HashTable也是一种key-value结构,key-value不允许null,并且这个类的几乎全部的方法都加上了synchronized锁,来保证并发安全,由于加了锁所以性能方面会比较 ...
- [转]net中哈希表的使用 Hashtable
本文转自:http://www.cnblogs.com/gsk99/archive/2011/08/28/2155988.html 以下是PetShop中DBHelper中的使用过程: //创建哈希表 ...
- 哈希表(hashtable)的javascript简单实现
javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...
- 哈希表(Hashtable)简述
一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...
- c/c++ 哈希表 hashtable
c/c++ 哈希表 hashtable 概念:用key去查找value 实现hash函数有很多方法,本文用除留余数法. 除留余数法的概念: 取一个固定的基数的余数,注意不能用偶数,用偶数的话,分布会不 ...
- js中哈希表的几种用法总结
本篇文章只要是对js中哈希表的几种用法进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1. <html> <head> <script type=" ...
随机推荐
- c# dll问题
问题描述: dll完全拷贝另一个程序,可是报缺少引用程序集之类的错误. 解决办法: 有可能是.net版本造成的错误.一般常见在3.5升到4之后,存在很多容差.
- HashMap get()返回值问题
问题描述:在进行mysql查询必要字段后,需要根据id进行es其它数据字段的查询拼接.使用HashMap以id为key 以查询过来的数据值为value. 代码如下: Map<String,Int ...
- 【Redis】- 安装为windows服务
1.安装redis服务 echo install redis-server redis-server.exe --service-install redis.windows.conf --loglev ...
- Linux下安装MySQL管理工具MySQL Administrator和MySQL Query Browser(转载)
文章来源:http://blog.csdn.net/sunrier/article/details/7572299 Linux下MySQL Administrator和MySQL Query Brow ...
- java 基础--数组--004
1,数组定义格式 String[] aa; String aa[];2,二位数组的定义格式1 String aa[][] = new String[m][n]; String[] aa[] = new ...
- Java多线程中的join方法
新建一个Thread,代码如下: package com.thread.test; public class MyThread extends Thread { private String name ...
- 使用 Python 操作 Git 版本库 - GitPython
GitPython 是一个用于操作 Git 版本库的 python 包, 它提供了一系列的对象模型(库 - Repo.树 - Tree.提交 - Commit等) 用于操作版本库中的相应对象. 版本库 ...
- 数据包从tcp->ip发出去
ip_local_out->OUTPUT->dst_out->ip_output-> POSTROUTING -->ip_output_finish 上面的路径中啊,在O ...
- mysql学习之数据备份与恢复
该文使用mysql5.5 centos6.5 64位(本人使用rpm安装mysql,数据库的安装目录默认) 一.数据备份注意事项 读锁问题:数据库(或者某个表)一旦进行读锁操作则影响数据库的写操作所以 ...
- [剑指Offer] 48.不用加减乘除做加法
题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 首先看十进制是如何做的: 5+7=12,三步走第一步:相加各位的值,不算进位,得到2.第二步:计算进 ...