哈希表提供了快速的插入操作和查找操作,每一个元素是一个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)的更多相关文章

  1. Java中哈希表(Hashtable)是如何实现的

    Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...

  2. java数据结构----哈希表

    1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...

  3. JAVA数据结构--哈希表的实现(分离链接法)

    哈希表(散列)的定义 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...

  4. java集合-哈希表HashTable

    一.简介 HashTable也是一种key-value结构,key-value不允许null,并且这个类的几乎全部的方法都加上了synchronized锁,来保证并发安全,由于加了锁所以性能方面会比较 ...

  5. Java数据结构——哈希表

  6. 哈希表(hashtable)的javascript简单实现

    javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...

  7. C#中哈希表(HashTable)的用法详解以及和Dictionary比较

    1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对, ...

  8. 数据结构 -- 哈希表(hash table)

    简介   哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  9. 哈希表(Hashtable)简述

    一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...

随机推荐

  1. Java中访问修饰符public、private、protecte、default

    Java中访问修饰符public.private.protecte.default的意义讲解:public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”.被其修饰的类.属性以及方法不 仅 ...

  2. win7 部署tomcat

    1,下载 jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u3-download-1501626.html 2,下载t ...

  3. .NET Core 单元测试

    应用程序测试的类型很多,包括集成测试,Web 测试,负载测试等.在最底层的是单元测试,此测试可以测试单个软件组件或方法.单元测试一般只测试开发人员的代码,不应该测试基础结构普.问题,如数据库,文件系统 ...

  4. SpringBoot:高并发下浏览量入库设计

    一.背景 文章浏览量统计,low的做法是:用户每次浏览,前端会发送一个GET请求获取一篇文章详情时,会把这篇文章的浏览量+1,存进数据库里. 1.1 这么做,有几个问题: 在GET请求的业务逻辑里进行 ...

  5. Spring学习之旅(二)--容器

    在 Spring 应用中,所有的对象都在 Spring 容器(container) 里,容器负责对象的创建.配置.装配并管理它们的整个生命周期. Spring 容器 Spring 容器 并不是只有一个 ...

  6. Windows GIT SSH 免密教程

    Windows GIT SSH 免密教程 安装git客户端,最新下载地址如下 https://github.com/git-for-windows/git/releases/download/v2.2 ...

  7. requests.get爬虫模块参数

    地址和请求头参数--url和header res = requests.get(url,headers=headers) 向网站发起请求,并获取响应对象 参数 url :需要抓取的URL地址 head ...

  8. git 如何实现进行多人协作开发(远程仓库)

    第一.Git作为分布式的版本控制系统,你是你本地仓库的主人,但是想要实现多人的协作开发,你就要将你本地的开发推送到远程共享仓库中供大家下载,本篇主要以github作为远程服务器来介绍有关远程仓库这块内 ...

  9. 洛谷 P3627 【抢掠计划】

    题库:洛谷 题号:3627 题目:抢掠计划 link:https://www.luogu.org/problem/P3627 思路 : 这道题是一道Tarjan + 最长路的题.首先,我们用Tarja ...

  10. [python]python字典

    1.简介 字典是python中的映射数据类型,由‘键-值’(key-value)对构成. 键:几乎所有类型的python对象都可以用作键,不过一般还是以数字或者字符串最为常用. 值:可以是任意类型的p ...