转自:https://blog.csdn.net/al_assad/article/details/52989525

散列和散列码
 
※正确的equals方法应该满足的的条件:
①自反性:x.equals(x) 一定返回true;
②对称性:y.euqlas(x)为true,那么x.equals(y)一定为true;
③传递性:x.equals(y)为true,y.euqlas(z)为true,则z.equals(x)为true;
④一致性:如果x,y中用于等价比较的信息没有变化,那么无论调用y.euqlas(x)多少次,结果都是一致的;
⑤对任何不是null的x,x.equals(null)一定为false;
 
1、在查询方式里,线性查询是最慢的查询方式;
2、散列的价值在于速度,它使用一组数组(Java中储存查询速度最快的数据结构)来储存键的信息(并非键本身);
     数组本身不保存键本身,而是通过键本身生成一个编码,将其作为数组下标,该编码就是散列码,由键的hashCode(散列函数)产生;
     数组保存的一个记录键的list,当在一个数组中的散列码发生冲突时,有外部链接解决冲突,并加入同一个list中;
3、在散列结构里查找一个键:
     ①计算该键的散列码,使用该散列码查询数组;
     ②对该数组下标的list使用根据equals进行线性查询;
4、散列表中的一些术语:
     ①容量:表中的桶buckets位数;
     ②初始容量:表在创建时拥有的桶位数,HashMap和HashSet都允许指定初始容量的构造器;
     ③尺寸:表中当前储存的位数;
     ④负载因子:尺寸/容量,空表负载为0,满表负载为1.0,负载轻产生的冲突可能性小,有利于插入和查询,但是会减慢使用迭代器遍历元素,默认的负载因子为0.75;
     ⑤再散列:当负载达到负载因子的水平时,容器会自动增加容量(双倍增加);
5、散列容器的模型:
 
6、hashCode的实现:
 
 
7、HashMap的实现和key元素实现散列码

  1. <span style="color:#000000;">import java.util.*;
  2. public class SimpleHashMap<K,V> extends AbstractMap<K,V>{
  3. static final int SIZE = 997;  //默认bucket数量;
  4. @SuppressWarnings("unchecked")
  5. LinkedList<MapEntry<K,V>>[] buckets = new LinkedList[SIZE];
  6. //放置映射关系,返回原先的映射Value;
  7. public V put (K key, V value){
  8. int index = Math.abs(key.hashCode()) % SIZE;
  9. if(buckets[index] == null)
  10. buckets[index] = new LinkedList<MapEntry<K, V>>();
  11. V oldValue = null;
  12. LinkedList<MapEntry<K,V>> bucket = buckets[index];
  13. MapEntry<K, V> pair = new MapEntry<K,V>(key,value);
  14. ListIterator<MapEntry<K,V>> iter = bucket.listIterator();
  15. //检查重复key,更新value
  16. boolean found = false;
  17. while(iter.hasNext()){
  18. MapEntry<K,V> tempPair = iter.next();
  19. if(tempPair.getKey().equals(key)){
  20. oldValue = tempPair.getValue();
  21. iter.set(pair);
  22. found = true;
  23. break;
  24. }
  25. }
  26. if(!found)
  27. buckets[index].add(pair);
  28. return oldValue;
  29. }
  30. public V get(Object key){
  31. int index = Math.abs(key.hashCode()) % SIZE;
  32. if(buckets[index] == null)
  33. return null;
  34. for(MapEntry<K,V> pair : buckets[index]){
  35. if(pair.getKey().equals(key))
  36. return pair.getValue();
  37. }
  38. return null;
  39. }
  40. @Override
  41. public Set<Map.Entry<K, V>> entrySet() {
  42. Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K,V>>();
  43. for(LinkedList<MapEntry<K,V>> bucket : buckets){
  44. if(bucket == null)
  45. continue;
  46. for(MapEntry<K,V> pair : bucket)
  47. set.add(pair);
  48. }
  49. return set;
  50. }
  51. class MapEntry<K,V> implements Map.Entry<K, V>{
  52. K key;
  53. V value;
  54. public MapEntry(K key,V value){
  55. this.key = key;
  56. this.value = value;
  57. }
  58. @Override
  59. public K getKey(){
  60. return  this.key;
  61. }
  62. @Override
  63. public V getValue() {
  64. return this.value;
  65. }
  66. @Override
  67. public V setValue(V value) {
  68. return this.value = value;
  69. }
  70. }
  71. /*实现可以引用在在HashMap对象的key对象,该对象必须实现hashCode方法*/
  72. import java.util.*;
  73. public class CountString {
  74. private static List<String> created = new ArrayList<String>();
  75. //用于记录一次程序运行创建的所哟 String s实例,当s发生重复时,生成唯一的id,以产生唯一的散列值;
  76. private String s ;        //用于记录内容的数据域
  77. private int id = 0;             //记录相同String的CountString对象的编号
  78. public CountString(String str){
  79. this.s = str;
  80. created.add(s);
  81. for(String e : created){
  82. if(e.equals(s))
  83. this.id++;
  84. }
  85. }
  86. public int hashCode(){
  87. int result = 17;                //设置初始偏移量
  88. result = 37*result + s.hashCode();            //37稀释值
  89. result = 37*result + id;               //进行第二次稀释,放置ID值破坏s.hasCode;
  90. return result;
  91. }
  92. public boolean equals(Object o){
  93. return o instanceof CountString && s.equals(((CountString)o).getS())
  94. && id == ((CountString)o).getId();
  95. }
  96. public String getS(){
  97. return this.s;
  98. }
  99. public int getId(){
  100. return  this.getId();
  101. }
  102. public String toString(){
  103. return "String:"+s+" id:"+id+" hashCode: "+hashCode();
  104. }
  105. }
  106. </span>

Java散列和散列码的实现的更多相关文章

  1. 【Java集合学习】HashMap源码之“拉链法”散列冲突的解决

    1.HashMap的概念 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io ...

  2. java 散列与散列码探讨 ,简单HashMap实现散列映射表运行各种操作示列

    java 散列与散列码探讨 ,简单HashMap实现散列映射表运行各种操作示列 package org.rui.collection2.maps; /** * 散列与散列码 * 将土拔鼠对象与预报对象 ...

  3. [转]java.sql.SQLException: 无效的列索引

    原文地址:http://blog.sina.com.cn/s/blog_6bc811e401011a17.html java.sql.SQLException: 无效的列索引 “无效的列索引”其实是个 ...

  4. java.sql.SQLException: 无效的列索引

    java.sql.SQLException: 无效的列索引 "无效的列索引"其实是个低级的错误,原因无非几个: 1.sql串的?号数目和提供的变量数目不一致: 例如:jdbcTem ...

  5. Java.sql.SQLException: 无效的列类型: 1111

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: ...

  6. Cause: java.sql.SQLException: 无效的列索引

    今天调试代码发现“Cause: java.sql.SQLException: 无效的列索引”,查资料得出结论如下: 1.sql串的?号用''括了起来. 例如:select* from user t  ...

  7. oracle: jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111

    https://www.cnblogs.com/mmlw/p/5808072.html org.mybatis.spring.MyBatisSystemException: nested except ...

  8. Java JTable列顺序和列宽度保存在用户本地

    上周碰到了一个棘手的需求,就是要把用JTable的列顺序和列宽度保存下来,这次用户调整了列宽度,关闭程序,下次再打开时,这个列的宽还是要保持,因为SWing的特性,都是在程序启动时就确定了列顺序和列宽 ...

  9. java学习-zxing生成二维码矩阵的简单例子

    这个例子需要使用google的开源项目zxing的核心jar包 core-3.2.0.jar 可以百度搜索下载jar文件,也可使用maven添加依赖 <dependency> <gr ...

随机推荐

  1. php引用(&)变量引用,函数引用,对象引用和参数引用用法

    php引用(&)变量引用,函数引用,对象引用和参数引用用法   php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语 ...

  2. 在需要隐藏navigationController控制器

    - (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated]; [self.navigationControll ...

  3. javascript常量的定义

    例如可以使用 const PI = 3.14159265; 一般不推荐使用 const 关键字,因为它不是 ECMAScript 语法的一部分.当需要常量的时候一般是以命名习惯来约束的,亦即使用大写字 ...

  4. Hadoop文件解压缩

    Class org.apache.hadoop.io.compress .CompressionCodecFactory A factory that will find the correct co ...

  5. Java多线程之内置锁与显示锁

    Java中具有通过Synchronized实现的内置锁,和ReentrantLock实现的显示锁,这两种锁各有各的好处,算是互有补充,今天就来做一个总结. Synchronized 内置锁获得锁和释放 ...

  6. SVN提交项目时版本冲突解决方案

    版本冲突原因: 假设A.B两个用户都在版本号为7的时候,更新了index.jsp这个文件,A用户在修改完成之后提交index.jsp到服务器,这个时候提交成功,这个时候index.jsp文件的版本号已 ...

  7. IE首页被篡改(手动修复)

    所谓手动修复,即以不变应万变,修改注册表,其实工具软件也只是帮你代工而已. win + R 打开 “运行”,键入 “regedit.exe” 打开注册表编辑器,在 路径 HKEY_LOCAL_MACH ...

  8. jsp中 自定义 tag的几种方式

    在jsp文件中,可以引用tag和tld文件. 1.对于tag文件,使用tagdir引用(这个直接是引用的后缀tag文件的jsp文件) <%@ taglib prefix="ui&quo ...

  9. hdu 1042 N! java大数及判断文件末尾

    N! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submi ...

  10. iOS 小数点精度问题处理

    实际开发中有时候经常会需要去处理小数点精度问题,如果是整数保留整数,如果有小数则保留不为0的的小数,最大2位小数 eg: 2.013 ---> 2.01 2.0 ---> 2 2.10 - ...