java数据结构——哈希表(HashTable)
哈希表提供了快速的插入操作和查找操作,每一个元素是一个key-value对,其基于数组来实现。
一、Java中HashMap与Hashtable的区别:
HashMap可以接受null键值和值,而Hashtable则不能。
Hashtable是线程安全的,通过synchronized实现线程同步。而HashMap是非线程安全的,但是速度比Hashtable快。
这两个类有许多不同的地方,下面列出了一部分:
a) Hashtable 是 JDK 1 遗留下来的类,而 HashMap 是后来增加的。
b)Hashtable 是同步(synchronized)的,比较慢,但 HashMap 没有同步策略,所以会更快。
c)Hashtable 不允许有个空的 key,但是 HashMap 允许出现一个 null key。
public class Employee {
private String key;
private String name;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(String key, String name) {
this.key = key;
this.name = name;
}
}
员工类
import java.math.BigInteger;
public class HashTable {
private Employee[] arr;
public HashTable() {
arr = new Employee[1000];
}
public HashTable(int Maxsize) {
arr = new Employee[Maxsize];
}
// public void Insert(Employee emplo) {//以整型作为索引
// arr[emplo.getKey()] = emplo;
// }
public void Insert(Employee emplo) {// 以字符串作为索引
arr[hashTable(emplo.getKey())] = emplo;
}
// public Employee Find(int key) {
// return arr[key];
// }
public Employee Find(String key) {
return arr[hashTable(key)];
}
public int hashTable(String key) {// 转换AscII码存储,但存在码值重复问题
BigInteger hashVal = new BigInteger("0");
BigInteger pow27 = new BigInteger("1");
// int hashVal = 0;
int i = key.length() - 1;
// int pow27 = 1;// 27^0
// for (; i >= 0; i--) {
// int letter = key.charAt(i) - 96;
// hashVal += letter;
// }
// return hashVal;
// }
for (; i >= 0; i--) {
int letter = key.charAt(i) - 96;
BigInteger letterB = new BigInteger(String.valueOf(letter));
hashVal = hashVal.add(letterB.multiply(pow27));// hashVal += letter * pow27;
// hashVal += letter * pow27;// 这里会溢出
// pow27*=27
pow27 = pow27.multiply(new BigInteger(String.valueOf(27)));
}
//return hashVal % arr.length;
return hashVal.mod(new BigInteger(String.valueOf(arr.length))).intValue();
}
}
方法类
public class Demo {
public static void main(String[] args) {
HashTable ht = new HashTable();
/*ht.Insert(new Employee(1, "Ally"));
ht.Insert(new Employee(2, "Jion"));
ht.Insert(new Employee(3, "Micale"));
ht.Insert(new Employee(4, "Lily"));
System.out.println(ht.Find(2).getName());*/
ht.Insert(new Employee("aka", "74"));
System.out.println(ht.Find("aka").getName());
}
}
演示类
链地址法
public class LinkList {
private Node first;// 火车头,保存头结点的一个指向
public LinkList() {// 初始化
first = null;
}
public Node deleteFirst() {// 删除头结点
first = first.next;// 头结点为头结点的下一个
return first;
}
public Node find(String key) {// 按值查找,返回null或索引值
Node current = first;// 从头结点开始
while (!key.equals(current.emplo.getKey())) {
if (current.next == null) {// 尾结点后继为null
return null;
}
current = current.next;
}
return current;// 找到返回
}
public Node delete(String key) {// 删除任意结点
Node current = first;
Node previous = first;
while (!key.equals(current.emplo.getKey())) {//找到current返回true !true = false
if (current.next == null) {// 没有找到
return null;
}
previous = current;// 保存邻近的两个结点
current = current.next;
}
if (current == first) {// 第一个结点
first = first.next;
} else {// 后面的结点
previous.next = current.next;// 上一个结点的下一个变为当前结点的下一个,当前结点删除
}
return current;// 结点类,返回结点类型
}
public void insert(Employee emplo) {// 在头结点之后插入
Node node = new Node(emplo);// 创建新的结点
// 这里深深体会一下精妙之处,first保存着一个指向
node.next = first;// 图示第一步
first = node;// 图示第二步
}
}
链表
public class Node {// 包装车厢
/**
* 链结点
*/
public Employee emplo;// 数据域
public Node next;// 指针域,后指针
public Node(Employee emplo) {// 构造函数
this.emplo = emplo;
}
}
结点
import java.math.BigInteger;
public class HashTable {
private LinkList[] arr; // 每个数值对应一个链表
public HashTable() {
arr = new LinkList[100];
}
public HashTable(int Maxsize) {
arr = new LinkList[Maxsize];
}
public void Insert(Employee emplo) {// 以字符串作为索引
String key = emplo.getKey();
int hashVal = hashTable(key);
if (arr[hashVal] == null) {
arr[hashVal] = new LinkList();
}
arr[hashVal].insert(emplo);
}
public Employee Find(String key) {
int hashVal = hashTable(key);
return arr[hashVal].find(key).emplo;
}
public Employee Delete(String key) {
int hashVal = hashTable(key);
return arr[hashVal].delete(key).emplo;
}
public int hashTable(String key) {// 转换AscII码存储,但存在码值重复问题
BigInteger hashVal = new BigInteger("0");
BigInteger pow27 = new BigInteger("1");
int i = key.length() - 1;
for (; i >= 0; i--) {
int letter = key.charAt(i) - 96;
BigInteger letterB = new BigInteger(String.valueOf(letter));
hashVal = hashVal.add(letterB.multiply(pow27));
pow27 = pow27.multiply(new BigInteger(String.valueOf(27)));
}
return hashVal.mod(new BigInteger(String.valueOf(arr.length))).intValue();
}
}
方法
public class Demo {
public static void main(String[] args) {
HashTable ht = new HashTable();
/*ht.Insert(new Employee(1, "Ally"));
ht.Insert(new Employee(2, "Jion"));
ht.Insert(new Employee(3, "Micale"));
ht.Insert(new Employee(4, "Lily"));
System.out.println(ht.Find(2).getName());*/
ht.Insert(new Employee("a", "Jack")); // 开放地址法
ht.Insert(new Employee("ct","Rose"));
ht.Insert(new Employee("b", "Upon"));
System.out.println(ht.Find("a").getName());//打印对象
System.out.println(ht.Find("ct").getName());
System.out.println(ht.Find("b").getName());
System.out.println(ht.hashTable("a"));
System.out.println(ht.hashTable("ct"));
}
}
测试


参考文献:
https://www.cnblogs.com/aeolian/p/8468632.html
https://www.cnblogs.com/williamjie/p/9099141.html
http://www.luyixian.cn/news_show_10979.aspx
java数据结构——哈希表(HashTable)的更多相关文章
- Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...
- java数据结构----哈希表
1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...
- JAVA数据结构--哈希表的实现(分离链接法)
哈希表(散列)的定义 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...
- java集合-哈希表HashTable
一.简介 HashTable也是一种key-value结构,key-value不允许null,并且这个类的几乎全部的方法都加上了synchronized锁,来保证并发安全,由于加了锁所以性能方面会比较 ...
- Java数据结构——哈希表
- 哈希表(hashtable)的javascript简单实现
javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...
- C#中哈希表(HashTable)的用法详解以及和Dictionary比较
1. 哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对, ...
- 数据结构 -- 哈希表(hash table)
简介 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...
- 哈希表(Hashtable)简述
一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...
随机推荐
- .NET导出Excel的四种方法及评测
.NET导出Excel的四种方法及评测 导出Excel是.NET的常见需求,开源社区.市场上,都提供了不少各式各样的Excel操作相关包.本文,我将使用NPOI.EPPlus.OpenXML.Aspo ...
- 做「容量预估」可没有true和false
如果第二次看到我的文章,欢迎右侧扫码订阅我哟~
- 用Python操作文件
用Python操作文件 用word操作一个文件的流程如下: 1.找到文件,双击打开. 2.读或修改. 3.保存&关闭. 用Python操作文件也差不多: f=open(filename) # ...
- HDU 1173 采矿
采矿 题解:如果给你一条线段(左右端点设为A,B), 那么在这条线上的任意一点到A B距离之和是一个定值, 然后如果再这条线段内在任意确定一个定点C, 那么这条线段上再任意取一个点,这个点到 A B ...
- Windows下安装youtube-dl(下载各大网站视频)
youtube-dl干什么用的? 惯例,看官方介绍: youtube-dl is a command-line program to download videos from YouTube.com ...
- 面向对象程序设计(Java) 第1周学习指导及要求
面向对象程序设计(Java)第1周学习指导及要求 (2019.8.30-2019.9.2) 学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 理解JVM.JRE与JDK等概念 ...
- hadoop历史服务的启动与停止
a.配置项(在分布式环境中配置) 1.RPC访问地址 mapreduce.jobhistory.address 2.HTTP访问地址 mapreduce.jobhistory.webapp.addre ...
- 搭建自己的技术博客系列(一)使用 hexo 搭建一个精美的静态博客
1.安装 Git 和 nodejs https://hexo.io/zh-cn/docs/
- Mybatis系列(一)入门
Mybatis系列(一)入门 mybatis简介 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结 ...
- day02小结
数据类型的转换 1,自动类型转换 byte,short,char-->int-->long-->float-->double (1)byte与byte,short与short, ...