您的位置:首页 > 编程语言 > Java开发

Java -- Map的底层实现

2017-05-10 11:09 253 查看
Java – Map的底层实现

一. 特性

map的特点是,无序,键值不能重复(如果重复,就覆盖value),利用键值寻找对象

二.map的实现(数组 + 链表)

本节课的目的是为了用哈希码和“数组+ 链表”的方式自己实现map

在01版本中,因为每次要查找键值是否重复(因为map的键值是不可重复的),都需要遍历数组,效率很低,因此,采用使用哈希码的方式定位,但因为数组的长度是有限的,而哈希码是无限的,所以改良数据结构,将数组和链表结合在一起实现map。

外用数组,数组中的每一个位置都是一个链表,然后用哈希码对数组大小取余来定位

先用哈希码来定位,然后在每个位置中,再遍历链表,查找键值是否重复,如果重复,之间覆盖。

Map的各种操作如下

元素

包括一个外数组,内链表

和一个size

MyLinklist[] map = new MyLinklist[999];
int size;


方法

1.

put 放进map,因为map的特性,键值不能重复,所以要判断是否重复

可以遍历数组,再遍历数组中每个位置的链表,然后用equals

但是这样效率太低,所以用键值的哈希码来定位数组中的位置

先用key的hashcode对数组的size取余,从而定位数组每个位置,(不过需要注意,hashcode很可能是负数,所以要加个判断)再遍历每个位置的链表,最后用equals

如果此位置是空,则新建一个链表,然后添加键值对

如果此位置非空,则遍历此位置的链表,然后挨个对比其key值,如果key重复,直接覆盖value;如果key值非空,新建一个结点,然后添加键值对

public void put(Object key, Object value) {
int hash = key.hashCode();
hash = hash > 0 ? hash :-hash;//判断哈希码是正还是负
int loc = hash% map.length;
int loc = key.hashCode() % map.length;
Entry entry = new Entry(key, value);
if (map[loc] == null) {
MyLinklist myLinklist = new MyLinklist();
myLinklist.add(entry);
map[loc] = myLinklist;
} else//数组的这个位置非空的时候
{
MyLinklist myLinklist = map[loc];
for (int i = 0; i < myLinklist.size; i++) {
Entry entry1 = (Entry) myLinklist.get(i);//获得这条链表的每个结点
if (entry1.key.equals(key)) {
entry1.value = value;
return;
}
}
//如果遍历一遍链表都没发现重复的key,就直接在此链表后添加键值对
myLinklist.add(entry);
map[loc] = myLinklist;

}
}


get方法,先用哈希码定位数组中的位置,然后遍历此位置的链表,再用equals比较键值,符合就返回value。遍历完都不符合,返回null

public Object get(Object key)
{
int loc = key.hashCode() % map.length;
MyLinklist myLinklist = map[loc];
if (map[loc] != null)
{
for (int i = 0; i < myLinklist.size; i++)
{
Entry entry = (Entry) myLinklist.get(i);
if (entry.key.equals(key))
return entry.value;
}
}
return null;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 地图