转自: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. JBOSS 中oracle-ds.xml的配置模板

    http://blog.csdn.net/bo_hai/article/details/6076979 JBOSS 中oracle-ds.xml的配置模板.   代码模版: <?xml vers ...

  2. 后台dubug有值且sql也打印出来执行了但是前台就是查不到数据

    记录在sturts2里面 摔得最深的一次 public String queryJoinAccount(){ //用来存储分页的数据 pageMap=new HashMap<String, Ob ...

  3. WebSocket遇到的一些问题

    一 .Nginx配置websocket   为了解决Nginx转发不能进行websocket通信问题 将nginx配置文件添加如下内容:   map $http_upgrade $connection ...

  4. Atitit.减少http请求数方案

    Atitit.减少http请求数方案 1. 原理与方法1 1.1. -------jsp1 1.2. "index/js.txt";2 1.3. connReduceDync2 1 ...

  5. atitit.浏览器web gui操作类库 和 操作chrome浏览器的类库使用总结

    atitit.浏览器web gui操作类库 和 操作chrome浏览器的类库使用总结 1. 常见标准 1 1.1. 录制重放 1 1.2. 一个窗体一个proxy cookie 1 1.3. exec ...

  6. [Egret]长按截屏分享、分享截屏图片、本地存储

    egret 分享有API可以把一个显示对象树渲染成一个位图纹理,我把它赋值给 HTML 的 Image 元素,就实现了图片的显示,在微信中,通过长按图片可以分享出去.当然在其他浏览器可以保存在本地. ...

  7. Oracle之函数concat、lpad

    一.引言 程序测试需要生成大量的测试数据,且测试数据有主键,主键自增,于是决定用存储过程来实现,经过半天的查资料终于完成了,记录之,学习之 二.存储过程 格式: CREATE PROCEDURE re ...

  8. 无语的Filezilla

    之前也一直用filezilla,今天遇到个奇葩问题:在2008R2上装完filezilla server,本打算生成个证书用于SSL加密,没想到一直报错"Failed to initiali ...

  9. shell变量/环境变量和set/env/export用法_转

    转自:shell环境变量以及set,env,export的区别 一.shell环境变量的分类以及set env export的区别: set:显示(设置)shell变量,包括的私有变量以及用户变量.不 ...

  10. LCD屏参数及应用举例

     1.  LCD参数及原理 R G B 信号 PCLK(像素时钟),LCLK(HSYNC,线时钟,水平同步时钟),FCLK(VSYNC,帧时钟,垂直同步时钟) 7寸屏一般由两种工作模式DE和时钟模式, ...