【ThinkingInJava】53、为了提高速度,我们使用散列

/**
* 书本:《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]





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值