君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

最近闲的很,想和大家一起学习并讨论下Java的一些源代码以及其实现的数据结构,

不是什么高水平的东西,有兴趣的随便看看

 

1. 为什么要用Map,以HashMap为例

    很多时候我们有这样的需求,我们需要将数据成键值对的方式存储起来,根据key来获取value(value可以是简单值,也可以是自定义对象)

    当然用对象数组也能实现这个目的,查找时可以遍历数组,比较关键字来获取对应的value

    从性能上来讲,遍历大数组会消耗性能

    从API易用性来讲,需要自己实现查找的逻辑

    所以用HashMap是必要的    

 

2. HashMap的数据结构是怎么样的

 

    我一直对HashMap的内部结构很好奇,看了源码之后发现他是用散列实现的,即基于hashcode

    大体思想是这样的

    1. 首先建立一个数组用来存取数据,假设我们定义一个Object[] table用来存取map的value

这个很容易理解,key存在哪里呢?暂时我不想存储key

    2. 获得key的hashcode经过一定算法转成一个整数

        index,这个index的取值范围必须是0=<index<table.length,然后我将其作为数组元素的下标

        比如执行这样的操作:table[index] = value;

        这样存储的问题解决了

    3. 如何通过key去获取这个value呢

        这个太简单了,首先获取key的hashcode,然后通过刚才一样的算法得出元素下标index

        然后value = table[index]

 

简单的HashTable实现如下

 

 

Java代码  收藏代码
  1. public class SimpleHashMap {  
  2.   
  3.     private Object[] table;  
  4.   
  5.     public SimpleHashMap() {  
  6.         table = new Object[10];  
  7.     }  
  8.   
  9.     public Object get(Object key) {  
  10.         int index = indexFor(hash(key.hashCode()), 10);  
  11.         return table[index];  
  12.     }  
  13.   
  14.     public void put(Object key, Object value) {  
  15.         int index = indexFor(hash(key.hashCode()), 10);  
  16.         table[index] = value;  
  17.     }  
  18.   
  19.     /** 
  20.      * 通过hash code 和table的length得到对应的数组下标 
  21.      *  
  22.      * @param h 
  23.      * @param length 
  24.      * @return 
  25.      */  
  26.     static int indexFor(int h, int length) {  
  27.         return h & (length - 1);  
  28.     }  
  29.   
  30.     /** 
  31.      * 通过一定算法计算出新的hash值 
  32.      *  
  33.      * @param h 
  34.      * @return 
  35.      */  
  36.     static int hash(int h) {  
  37.         h ^= (h >>> 20) ^ (h >>> 12);  
  38.         return h ^ (h >>> 7) ^ (h >>> 4);  
  39.     }  
  40.       
  41.       
  42.     public static void main(String[] args){  
  43.         SimpleHashMap hashMap = new SimpleHashMap();  
  44.         hashMap.put("key""value");  
  45.         System.out.println(hashMap.get("key"));  
  46.     }  
  47. }  

 

这个简单的例子大概描述了散列实现hashmap的过程

但是还很不成熟,我发现至少存在以下两个问题

1. hashmap的size是固定的

2. 如果不同的key通过hashcode得出的index相同呢,这样的情况是存在的,如何解决?

请看系列文章二

posted on 2013-07-15 03:37  刺猬的温驯  阅读(32)  评论(0)    收藏  举报