哈希表提供了快速的插入操作和查找操作,每一个元素是一个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。

  1. public class Employee {
  2. private String key;
  3. private String name;
  4.  
  5. public String getKey() {
  6. return key;
  7. }
  8.  
  9. public void setKey(String key) {
  10. this.key = key;
  11. }
  12.  
  13. public String getName() {
  14. return name;
  15. }
  16.  
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20.  
  21. public Employee(String key, String name) {
  22. this.key = key;
  23. this.name = name;
  24. }
  25. }

员工类

  1. import java.math.BigInteger;
  2.  
  3. public class HashTable {
  4. private Employee[] arr;
  5.  
  6. public HashTable() {
  7. arr = new Employee[1000];
  8. }
  9.  
  10. public HashTable(int Maxsize) {
  11. arr = new Employee[Maxsize];
  12. }
  13.  
  14. // public void Insert(Employee emplo) {//以整型作为索引
  15. // arr[emplo.getKey()] = emplo;
  16. // }
  17.  
  18. public void Insert(Employee emplo) {// 以字符串作为索引
  19. arr[hashTable(emplo.getKey())] = emplo;
  20. }
  21.  
  22. // public Employee Find(int key) {
  23. // return arr[key];
  24. // }
  25.  
  26. public Employee Find(String key) {
  27. return arr[hashTable(key)];
  28. }
  29.  
  30. public int hashTable(String key) {// 转换AscII码存储,但存在码值重复问题
  31. BigInteger hashVal = new BigInteger("0");
  32. BigInteger pow27 = new BigInteger("1");
  33.  
  34. // int hashVal = 0;
  35. int i = key.length() - 1;
  36. // int pow27 = 1;// 27^0
  37. // for (; i >= 0; i--) {
  38. // int letter = key.charAt(i) - 96;
  39. // hashVal += letter;
  40. // }
  41. // return hashVal;
  42. // }
  43. for (; i >= 0; i--) {
  44. int letter = key.charAt(i) - 96;
  45. BigInteger letterB = new BigInteger(String.valueOf(letter));
  46. hashVal = hashVal.add(letterB.multiply(pow27));// hashVal += letter * pow27;
  47.  
  48. // hashVal += letter * pow27;// 这里会溢出
  49. // pow27*=27
  50. pow27 = pow27.multiply(new BigInteger(String.valueOf(27)));
  51. }
  52. //return hashVal % arr.length;
  53. return hashVal.mod(new BigInteger(String.valueOf(arr.length))).intValue();
  54.  
  55. }
  56. }

方法类

  1. public class Demo {
  2.  
  3. public static void main(String[] args) {
  4. HashTable ht = new HashTable();
  5. /*ht.Insert(new Employee(1, "Ally"));
  6. ht.Insert(new Employee(2, "Jion"));
  7. ht.Insert(new Employee(3, "Micale"));
  8. ht.Insert(new Employee(4, "Lily"));
  9.  
  10. System.out.println(ht.Find(2).getName());*/
  11.  
  12. ht.Insert(new Employee("aka", "74"));
  13.  
  14. System.out.println(ht.Find("aka").getName());
  15. }
  16.  
  17. }

演示类

链地址法

  1. public class LinkList {
  2. private Node first;// 火车头,保存头结点的一个指向
  3.  
  4. public LinkList() {// 初始化
  5. first = null;
  6. }
  7.  
  8. public Node deleteFirst() {// 删除头结点
  9. first = first.next;// 头结点为头结点的下一个
  10. return first;
  11. }
  12.  
  13. public Node find(String key) {// 按值查找,返回null或索引值
  14. Node current = first;// 从头结点开始
  15.  
  16. while (!key.equals(current.emplo.getKey())) {
  17.  
  18. if (current.next == null) {// 尾结点后继为null
  19. return null;
  20. }
  21. current = current.next;
  22. }
  23. return current;// 找到返回
  24. }
  25.  
  26. public Node delete(String key) {// 删除任意结点
  27. Node current = first;
  28. Node previous = first;
  29.  
  30. while (!key.equals(current.emplo.getKey())) {//找到current返回true !true = false
  31. if (current.next == null) {// 没有找到
  32. return null;
  33. }
  34. previous = current;// 保存邻近的两个结点
  35. current = current.next;
  36. }
  37.  
  38. if (current == first) {// 第一个结点
  39. first = first.next;
  40. } else {// 后面的结点
  41. previous.next = current.next;// 上一个结点的下一个变为当前结点的下一个,当前结点删除
  42. }
  43. return current;// 结点类,返回结点类型
  44. }
  45.  
  46. public void insert(Employee emplo) {// 在头结点之后插入
  47. Node node = new Node(emplo);// 创建新的结点
  48. // 这里深深体会一下精妙之处,first保存着一个指向
  49. node.next = first;// 图示第一步
  50. first = node;// 图示第二步
  51. }
  52.  
  53. }

链表

  1. public class Node {// 包装车厢
  2. /**
  3. * 链结点
  4. */
  5. public Employee emplo;// 数据域
  6. public Node next;// 指针域,后指针
  7.  
  8. public Node(Employee emplo) {// 构造函数
  9. this.emplo = emplo;
  10. }
  11.  
  12. }

结点

  1. import java.math.BigInteger;
  2.  
  3. public class HashTable {
  4. private LinkList[] arr; // 每个数值对应一个链表
  5.  
  6. public HashTable() {
  7. arr = new LinkList[100];
  8. }
  9.  
  10. public HashTable(int Maxsize) {
  11. arr = new LinkList[Maxsize];
  12. }
  13.  
  14. public void Insert(Employee emplo) {// 以字符串作为索引
  15. String key = emplo.getKey();
  16. int hashVal = hashTable(key);
  17. if (arr[hashVal] == null) {
  18. arr[hashVal] = new LinkList();
  19. }
  20. arr[hashVal].insert(emplo);
  21. }
  22.  
  23. public Employee Find(String key) {
  24. int hashVal = hashTable(key);
  25. return arr[hashVal].find(key).emplo;
  26. }
  27.  
  28. public Employee Delete(String key) {
  29. int hashVal = hashTable(key);
  30. return arr[hashVal].delete(key).emplo;
  31. }
  32.  
  33. public int hashTable(String key) {// 转换AscII码存储,但存在码值重复问题
  34. BigInteger hashVal = new BigInteger("0");
  35. BigInteger pow27 = new BigInteger("1");
  36.  
  37. int i = key.length() - 1;
  38. for (; i >= 0; i--) {
  39. int letter = key.charAt(i) - 96;
  40. BigInteger letterB = new BigInteger(String.valueOf(letter));
  41. hashVal = hashVal.add(letterB.multiply(pow27));
  42.  
  43. pow27 = pow27.multiply(new BigInteger(String.valueOf(27)));
  44. }
  45. return hashVal.mod(new BigInteger(String.valueOf(arr.length))).intValue();
  46.  
  47. }
  48. }

方法

  1. public class Demo {
  2.  
  3. public static void main(String[] args) {
  4. HashTable ht = new HashTable();
  5. /*ht.Insert(new Employee(1, "Ally"));
  6. ht.Insert(new Employee(2, "Jion"));
  7. ht.Insert(new Employee(3, "Micale"));
  8. ht.Insert(new Employee(4, "Lily"));
  9.  
  10. System.out.println(ht.Find(2).getName());*/
  11. ht.Insert(new Employee("a", "Jack")); // 开放地址法
  12. ht.Insert(new Employee("ct","Rose"));
  13. ht.Insert(new Employee("b", "Upon"));
  14.  
  15. System.out.println(ht.Find("a").getName());//打印对象
  16. System.out.println(ht.Find("ct").getName());
  17. System.out.println(ht.Find("b").getName());
  18.  
  19. System.out.println(ht.hashTable("a"));
  20. System.out.println(ht.hashTable("ct"));
  21. }
  22.  
  23. }

测试

参考文献:

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. TensorFlow Object Detection API 迁移学习

    https://blog.csdn.net/ctwy291314/article/details/80999645 https://www.cnblogs.com/gmhappy/p/9472361. ...

  2. Spring学习之旅(一)--初始Spring

    之前从博客.视频断断续续的学到了 Spring 的相关知识,但是都是一个个碎片化的知识.刚好最近在读 <Sprign实战(第四版)>,所以借此机会重新整理下Spring 系列的内容. Sp ...

  3. 关于line-height 行高的一些理解和技巧

    大家都知道,如何设置文字垂直居中,也就是:设置line-height 和 外围盒子的高度height一致: 其实这里有个地方,是多余的,也就是height,设不设置都居中: 那么,行高是生产高度的? ...

  4. 特殊字符处理 java-jsp

    public String dealStr(String name){ String newStr=""; if(name != null && name.leng ...

  5. 证书pfx转jks

    keytool -importkeystore -srckeystore  2756649_order.hanels-home.com.pfx -srcstoretype pkcs12 -destke ...

  6. SCRUM术语

    http://www.scrumcn.com/agile/scrum-knowledge-library/scrum.html#tab-id-2 Scrum: Scrum无对应中文翻译 Agile: ...

  7. UOJ 34 多项式乘法 FFT 模板

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  8. JSP内置对象(一)

    一.out对象out对象是JspWriter类的实例,是向客户端输出内容常用的对象1.void println() out的println()方法,向客户端打印字符串 2. void clear() ...

  9. Day004作业

    1,写代码,有如下列列表,按照要求实现每⼀一个功能li = ["alex", "WuSir", "ritian", "barry& ...

  10. 代码质量检测(SonarQube)整合中文版+阿里P3C

    代码质量检测(SonarQube)整合中文版+阿里P3C 简介 SonarQube是一种自动代码审查工具,用于检测代码中的错误,漏洞和代码异味.它可以与您现有的工作流程集成,以便在项目分支和拉取请求之 ...