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的键值对,其中 ...
随机推荐
- app发布当天,用户无法登录
原因:当用户登录时候有商城用户的触发器存在,它会让商城用户也更新成登录状态. 由于用户量大,导致数据库锁死. 最后解决案:删掉触发器,在app的接口登录程序里,追加商城用户更新成登录的操作. 他案1: ...
- keras+ ctpn 原理流程图
- tesseract4.0:win10 +x64+vs2015 源码安装(ViewerDebugging)安装记录
参考文章: https://blog.csdn.net/u013985291/article/details/78295789 https://blog.csdn.net/u013985291/art ...
- 随笔编号-05 BigDecimal 处理集合
1 创建一个BigDecimal 对象 BigDecimal Sum = new BigDecimal(0); 2 一个BigDecimal 对象,保留2位小数点 Sum.setScale(2,B ...
- Spring学习之旅(十二)--持久化框架
对于本职工作来说 JDBC 就可以很好的完成,但是当我们对持久化的需求变得更复杂时,如: 延迟加载 预先抓取 级联 JDBC 就不能满足了,我们需要使用 ORM框架 来实现这些需求. Spring 对 ...
- Flink中Periodic水印和Punctuated水印实现原理(源码分析)
在用户代码中,我们设置生成水印和事件时间的方法assignTimestampsAndWatermarks()中这里有个方法的重载 我们传入的对象分为两种 AssignerWithPunctuatedW ...
- unity之局域网
Unity自5.1以后支持新版的网络系统Unet,Unet是什么,优缺点是什么,和以前的网络系统有什么区别,请自行去百度.本篇要实现的功能是创建网络游戏的Player主角,以及实现移动同步.本教程来源 ...
- 12 redis搭建主从服务(ubuntu)
什么是主从服务 一个master可以拥有多个slave,一个slave可以拥有多个slave,如此下去,形成了多级服务器集群架构 master用来写数据, slave用来读数据, 经统计:网站的读写比 ...
- Zookeeper之Leader选举过程
Leader在集群中是一个非常重要的角色,负责了整个事务的处理和调度,保证分布式数据一致性的关键所在.既然Leader在ZooKeeper集群中这么重要所以一定要保证集群在任何时候都有且仅有一个Lea ...
- HDU 6394 Tree 分块 || lct
Tree 题意: 给你一颗树, 每一个节点都有一个权值, 如果一个石头落在某个节点上, 他就会往上跳这个的点的权值步. 现在有2种操作, 1 把一个石头放在 x 的位置 询问有跳几次才跳出这棵树, 2 ...