实现一个map,重点是要查询快,所以map的基础是数组,接下来要解决的问题就是如何计算索引了,用key的hashcode经过一个算法得到一个索引,算法的问题不在此讨论,一般的摘要算法都可行。最后通过索引把kay-value存在数组中。那么问题来了,万一索引相同肿么办,一般有移位(即把索引往下挪一个),双向hash法(一个计算index,一个计算步长),在这里我用了主流的拉链法,就是数组加链表的组合,如果索引相同了,就往链表上加,大概原理就这样。代码很粗,仅供参考
目前这个map存在的问题还很多
1:map初始化大小的问题
2:计算索引的算法(将KEY进行某种算法得到一个int值,将这个值作为存入map中数组的索引,
但是这个值有时会很大,这样就需要数组的初始化大小特别大,这就造成了内存的浪费)
3:还没有做泛型的支持
4:key值相同未进行替换
5:自己这个链表的实现,操作比较麻烦
package map;
public class MyMap {
Node[] nodes;
int intsize;
private MyMap(int intsize) {
this.intsize = intsize;
nodes = new Node[intsize];
}
/**
* 初始化大小,需要优化
*/
public MyMap() {
this(1024*1024);
}
public boolean isEmpty(){
return intsize == 0;
}
public void put(Object key, Object value){
int index = hash(key);
Node newNode = new Node(index, key, value);
if(nodes[index] == null){
nodes[index] = newNode;
}else{
Node lastNode = nodes[index].getLastNode();
lastNode.setNext(newNode);
}
}
public Object get(Object key){
int index = hash(key);
Node startNode = nodes[index];
if(startNode == null){
return null;
}else if (startNode.getKey() == key) {
return startNode.getValue();
}else{
Node node = startNode.getNode(key);
if(node == null){
return null;
}
return node.getValue();
}
}
/**
* 计算hash值,即在数组中的索引,以后进行优化
* @param key
* @return
*/
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
}
class Node{
Object key;
Object value;
int index;
Node next;
public Node(int index, Object key, Object value) {
this.key = key;
this.value = value;
this.index = index;
}
public boolean isLast(){
return this.next == null;
}
/**
* 获取链表中与key相同的节点
* @param key
* @return
*/
public Node getNode(Object key){
if(key == this.key){
return this;
}
if(next != null){
return next.getNode(key);
}
return null;
}
public Node getLastNode(){
if(this.next == null){
return this;
}
return this.next.getLastNode();
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Object getKey() {
return key;
}
public Object getValue() {
return value;
}
}