/**
* 书本:《Thinking In Java》
* 功能:为了提高速度,我们使用散列
* 散列的价值在于速度:散列使得查询得以快速进行。由于瓶颈位于键的查询速度,因此解决方案之一就是保持键的排序状态,
* 然后使用Collections.binarySearch()进行查询
* 文件:SimpleHashMap.java
* 时间:2015年5月4日08:01:00
* 作者:cutter_point
*/
package Lesson17Containers;
import java.util.AbstractMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import net.mindview.util.Countries;
public class SimpleHashMap<K, V> extends AbstractMap<K, V>
{
//首先设定一下大小
static final int SIZE = 998;
//创建一个链表数组,链表里面存放的是mapentry
@SuppressWarnings(value ={ "unchecked" })
LinkedList<MapEntry<K, V>>[] buckets = new LinkedList[SIZE];
@Override
public V get(Object key)
{
//这里我觉得大家可以百度一下散列函数的知识
// Math.abs这个是返回绝对值
int index = Math.abs(key.hashCode()) % SIZE; //获取散列值,取余
//根据散列值对应的索引查找值
if(buckets[index] == null)
return null;
//如果存在这个值,那么就取出来
for(MapEntry<K, V> iPair : buckets[index]) //取出对应的这个index里面的mapentry,因为可能存在冲突
{
if(iPair.getKey().equals(key))
{
//找到匹配的
return iPair.getValue(); //返回值
}
}
//找不到就返回空
return null;
}
@Override
public V put(K key, V value) //放进去一个个值
{
V oldValue = null;
// Math.abs这个是返回绝对值
int index = Math.abs(key.hashCode()) % SIZE; //获取散列值,取余
//根据散列值对应的索引查找值,如果为空的话,那就创建一个新的加进去
if(buckets[index] == null)
{
buckets[index] = new LinkedList<MapEntry<K, V>>();
}
LinkedList<MapEntry<K, V>> bucket = buckets[index]; //得到这个mapentry
//我们定义一个boolean,来判断这个mapentry里面是不是含有我们要的值
boolean found = false;
ListIterator<MapEntry<K, V>> it = bucket.listIterator(); //这个ListIterator迭代器可以对里面的值进行修改
MapEntry<K, V> pair = new MapEntry<K, V>(key, value); //这个是要插入的值
//接下来开始查找,找到了就把found设定为true
while(it.hasNext())
{
//首先取出来相应entry
MapEntry<K, V> iPair = it.next();
//然后根据entry得到相应的value,如果得到了value,重新设定值,代替原来的值
if(iPair.getKey().equals(key))
{
oldValue = iPair.getValue();
it.set(pair);
found = true; //吧这个我们用来判断是否找到的boolean改为真
break;
}
}
//我们判定一下是否找到了,如果找到了,那就添加到里面去
if(!found)
buckets[index].add(pair);
return oldValue; //返回旧值
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet()
{
Set<Map.Entry<K, V>> set = new HashSet<Map.Entry<K, V>>(); //创建一个set存放entry
//吧buckets里面的值取出来放到set中
for(LinkedList<MapEntry<K, V>> bucket : buckets)
{
if(bucket == null)
continue; //如果是空的,那么就下一个循环
for(MapEntry<K, V> mpair : bucket)
{
set.add(mpair);
}
}
return set;
}
public static void main(String[] args)
{
SimpleHashMap<String, String> m = new SimpleHashMap<String, String>();
m.putAll(Countries.capitals(25));
System.out.println(m); //这个和第三个是不一样的,这个是输出键值对,下面输出的是一个数组
System.out.println(m.get("ERITREA"));
System.out.println(m.entrySet());
}
}
输出:
{CHAD=N'djamena, BISSAU=Bissau, CONGO=Brazzaville, BURUNDI=Bujumbura, DJIBOUTI=Dijibouti, EQUATORIAL GUINEA=Malabo, EGYPT=Cairo, GUINEA=Conakry, LESOTHO=Maseru, GHANA=Accra, BENIN=Porto-Novo, CENTRAL AFRICAN REPUBLIC=Bangui, GABON=Libreville, COTE D'IVOIR (IVORY COAST)=Yamoussoukro, KENYA=Nairobi, ETHIOPIA=Addis Ababa, ALGERIA=Algiers, BOTSWANA=Gaberone, COMOROS=Moroni, ANGOLA=Luanda, ERITREA=Asmara, CAPE VERDE=Praia, BURKINA FASO=Ouagadougou, THE GAMBIA=Banjul, CAMEROON=Yaounde}
Asmara
[CHAD=N'djamena, BISSAU=Bissau, CONGO=Brazzaville, BURUNDI=Bujumbura, DJIBOUTI=Dijibouti, EQUATORIAL GUINEA=Malabo, EGYPT=Cairo, GUINEA=Conakry, LESOTHO=Maseru, GHANA=Accra, BENIN=Porto-Novo, CENTRAL AFRICAN REPUBLIC=Bangui, GABON=Libreville, COTE D'IVOIR (IVORY COAST)=Yamoussoukro, KENYA=Nairobi, ETHIOPIA=Addis Ababa, ALGERIA=Algiers, BOTSWANA=Gaberone, COMOROS=Moroni, ANGOLA=Luanda, ERITREA=Asmara, CAPE VERDE=Praia, BURKINA FASO=Ouagadougou, THE GAMBIA=Banjul, CAMEROON=Yaounde]