`
bearsorry
  • 浏览: 93967 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

用java分析hash表结构及性能(二)

 
阅读更多

七,用代码来验证自己写的hash表以及性能分析(之前的rehash方法写错了,现在更正过来了!)

package cn.java1118;
/**
 * 自己写的hashmap类
 * @author acer
 *
 * @param <K>:关键字类
 * @param <V>:数据域类
 */
public class MyHashMap04<K,V> {

	//存放键值对的数组
	private Entry<K,V>[] hashTable;
	//当前容量的大小
	private int numberOfEntries;
	//装载因子
	private static final double MAX_LOAD_FACTOR=0.75;
	//集合初始化的一个大小
	static final int DEFAULT_INITIAL_CAPACITY = 16;
	
	public MyHashMap04(){
		this(DEFAULT_INITIAL_CAPACITY);
	}
	
	public MyHashMap04(int tablesize){
		//实例化数组的大小
		hashTable = new Entry[tablesize];
		//初始化的时候hash表里面什么都木有
		this.numberOfEntries=0;
	}
	/**
	 * 补充哈希函数
	 * @param h:每一个对象都有的hashcode
	 * @return:另一种hashcode
	 */
	static int hash(int h) {
		//直接copyJDK自带的这个算法
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
	
	/**
	 * 根据key取得value值
	 * @param key:键
	 * @return:键所对应的值
	 */
	public V getValue(K key){
		
		//要返回的值
		V result = null;
		//得到要key在数组的下标
		int hash = hash(key.hashCode());
		int index = indexFor(hash, hashTable.length);
		//对键值对链表进行遍历
		for (Entry<K,V> e = hashTable[index]; e != null; e = e.next) {
	            Object k;
	            if (e.hash == hash && ((k = e.key) == key || key.equals(k))){
	                return e.value;
	            }
	        }
		return result;
	}
	/**
	 * 添加元素
	 * @param key
	 * @param value
	 * @return:添加成功则为null,否则返回之前的值
	 */
	public V add(K key,V value){
		//键值为null时的处理方法
		if (key == null)
            return putForNullKey(value);
		//返回值变量
		V oldValue;
		
		//得到这个键在数组中的下标
		int hash = hash(key.hashCode());
		int index = indexFor(hash, hashTable.length);
		//看是否存在一样的键和hashcode
		for (Entry<K,V> e = hashTable[index]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            	//存在这样的键值对了
                oldValue = e.value;
                e.value = value;
               
                return oldValue;
            }
        }
		//插入一个键值对的时候当前的容量会+1
		numberOfEntries++;
		//进行插入
		addEntry(hash, key, value, index);
		return null;
	}
	/**
	 * 当插入的键位null时的处理
	 * @param value:值
	 * @return:插入成功则返回null,不成功则返回这个键原来所对应的值
	 */
	private V putForNullKey(V value) {
        for (Entry<K,V> e = hashTable[0]; e != null; e = e.next) {
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }
        numberOfEntries++;
        addEntry(0, null, value, 0);
        return null;
    }
	/**
	 * 插入键值对链表
	 * @param hash:hashcode
	 * @param key:键
	 * @param value:值
	 * @param bucketIndex:数组上的下标
	 */
	void addEntry(int hash, K key, V value, int bucketIndex) {
		//将原来的保留
		Entry<K,V> e = hashTable[bucketIndex];
		//在原来的基础上添加
		hashTable[bucketIndex] = new Entry<K,V>(hash, key, value, e);
		if(!isHashTableTooFull()){
			//看是否超出其装载因子
			rehash();
		}
	    }
	
	//检验hash表的装载因子是否大于默认值
	private boolean isHashTableTooFull() {
		//装载因子是有大小限制的
		if(numberOfEntries/hashTable.length>=MAX_LOAD_FACTOR){
			return false;
		}
		return true;
	}

	/**
	 * 再hash的方法
	 */
	private void rehash() {
		//保留原hash表
		Entry<K, V>[] oldHashTable = hashTable;
		int oldSize = hashTable.length;
		//扩大为原来的两倍
		int newSize = oldSize*2;
		hashTable = new Entry[newSize];
		numberOfEntries=0;
		
		//还要遍历原hash表,即将原来放进来的数据重新插入到新的hash表中
		for(int i=0;i<oldHashTable.length;i++){
			Entry<K, V> e = oldHashTable[i];
			if(e!=null){
				do{
					Entry<K, V> next = e.next;
				int index = indexFor(hash(e.hash), newSize);
			addEntry(e.hash, e.key, e.value, index);
			e=next;
				}while(e!=null);
				
			}
		}
	}
	/**
	 * 删除指定key的键值对
	 * @param key:键
	 * @return
	 */
	 public V remove(Object key) {
	        Entry<K,V> e = removeEntryForKey(key);
	        return (e == null ? null : e.value);
	    }
	 /**
	  * 跟查找的过程差不多
	  * @param key
	  * @return
	  */
	 final Entry<K,V> removeEntryForKey(Object key) {
	        int hash = (key == null) ? 0 : hash(key.hashCode());
	        int i = indexFor(hash, hashTable.length);
	        Entry<K,V> prev = hashTable[i];
	        Entry<K,V> e = prev;

	        while (e != null) {
	            Entry<K,V> next = e.next;
	            Object k;
	            if (e.hash == hash &&
	                ((k = e.key) == key || (key != null && key.equals(k)))) {
	                numberOfEntries--;
	                if (prev == e)
	                    hashTable[i] = next;
	                else
	                    prev.next = next;
	                return e;
	            }
	            prev = e;
	            e = next;
	        }

	        return e;
	    }
	 
	/**
	 * 得到在数组中的下标位置
	 * @param h:hashcode
	 * @param length:hash表的长度
	 * @return:下标位置
	 */
	static int indexFor(int h, int length) {
        return h & (length-1);
    }
	/**
	 * 实例化一个装键值对链表
	 * @author acer
	 *
	 * @param <K>
	 * @param <V>
	 */
	private class Entry<K,V>{
		private K key;
		private V value;
		//每一个对象都有一个hashcode,是唯一的,在map中不能存放hashcode一样的对象
		private int hash;
		//下一个键值对节点
		private Entry<K,V> next;
		
		private Entry(int hash,K key,V value,Entry<K,V>next){
			this.key = key;
			this.value = value;
			this.next = next;
			this.hash = hash;
		}

		public K getKey() {
			return key;
		}

		public V getValue() {
			return value;
		}
		//重写equals方法
		 public final boolean equals(Object o) {
	            if (!(o instanceof Entry))
	                return false;
	            Entry e = (Entry)o;
	            //得到两个比较的key值
	            Object k1 = getKey();
	            Object k2 = e.getKey();
	            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
	            	//得到两个比较的value值
	                Object v1 = getValue();
	                Object v2 = e.getValue();
	                if (v1 == v2 || (v1 != null && v1.equals(v2)))
	                    return true;
	            }
	            return false;
	        }
	}
}

 

  

性能分析代码:

package cn.java1118;

import java.util.HashMap;

public class Test1 {  
	  
    public static void main(String[] args) {  
    	//自己的hashmap
    	MyHashMap04<String, String> mm = new MyHashMap04<String, String>();   
        Long aBeginTime=System.currentTimeMillis();  
        for(int i=0;i<1000000;i++){  
        mm.add(""+i, ""+i*100);  
        }  
        Long aEndTime=System.currentTimeMillis();//记录EndTime  
        System.out.println("insert time-->"+(aEndTime-aBeginTime));  
          
        Long lBeginTime=System.currentTimeMillis();//记录BeginTime  
        mm.getValue(""+100000);  
        Long lEndTime=System.currentTimeMillis();//记录EndTime  
        System.out.println("seach time--->"+(lEndTime-lBeginTime));
        
        Long rBeginTime=System.currentTimeMillis();//记录BeginTime  
        mm.remove(""+10000);  
        Long rEndTime=System.currentTimeMillis();//记录EndTime  
        System.out.println("remove time--->"+(rEndTime-rBeginTime));
    	
    	//系统的hashmap
//    	HashMap<String, String> mm = new HashMap<String, String>();   
//        Long aBeginTime=System.currentTimeMillis();//记录BeginTime  
//        for(int i=0;i<1000000;i++){  
//        mm.put(""+i, ""+i*100);  
//        }  
//        Long aEndTime=System.currentTimeMillis();//记录EndTime  
//        System.out.println("insert time-->"+(aEndTime-aBeginTime));  
//          
//        Long lBeginTime=System.currentTimeMillis();//记录BeginTime  
//        mm.get(""+100000);  
//        Long lEndTime=System.currentTimeMillis();//记录EndTime  
//        System.out.println("seach time--->"+(lEndTime-lBeginTime));
//        
//        Long rBeginTime=System.currentTimeMillis();//记录BeginTime  
//        mm.remove(""+10000);  
//        Long rEndTime=System.currentTimeMillis();//记录EndTime  
//        System.out.println("remove time--->"+(rEndTime-rBeginTime));
    }  
}  
 

  

 


 

 

系统的测试结果:

insert time-->2148
seach time--->0

我的测试结果:

insert time-->2236
seach time--->0
remove time--->0

看,查找的速度为0呃,插入也只要2秒多。。。

 

还有一个是存储空间的测试:

 

 

 

 

 

<!--EndFragment-->

分享到:
评论

相关推荐

    哈希计算工具 java-hash.7z

    综上所述,`java-hash.7z` 工具包可能包含用于Java环境下的各种哈希计算工具和示例,帮助开发者进行数据校验、安全存储、性能优化等工作。通过理解和应用这些哈希计算技术,可以提升软件的安全性和效率。

    数据结构与算法分析 java语言描述第三版 源代码

    这本书通过使用Java编程语言,向读者展示了如何设计、实现和分析一系列关键的数据结构和算法,以解决实际问题。书中的源代码是理解理论知识与实际应用之间的桥梁,为学习者提供了实践操作的机会。 首先,我们来看...

    打造最快的Hash表(和Blizzard的对话)

    通过上述分析,我们可以看到Blizzard的Hash表实现不仅体现了对散列技术的深刻理解,而且还展示了如何利用多个散列值来进一步提高Hash表的性能和准确性。这种技术尤其适用于处理大量数据的情况,能够显著减少冲突的...

    数据结构与算法分析_Java语言描述(第3版)源码分享

    《数据结构与算法分析_Java语言描述(第3版)》是一本深入探讨数据结构和算法分析的专业书籍,它以Java编程语言为载体,详细阐述了如何高效地组织和操作大量数据,以及如何评估和比较不同算法的性能。这本书不仅涵盖了...

    Java里多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)

    在Java编程中,Map接口是用于存储键值对的数据结构,而Java提供了多种Map的实现,包括TreeMap、HashMap和ConcurrentSkipListMap。本文主要比较了这三种Map的性能,尤其是在插入和查找操作上的效率。 1. **TreeMap**...

    数据结构 课件java版本

    本课件“数据结构 课件java版本”是基于Java编程语言来讲解这一主题的,旨在帮助学生和开发者深入理解数据结构的基本概念,并掌握用Java实现这些数据结构的方法。 在Java中,数据结构主要分为以下几类: 1. **数组...

    数据结构与算法分析java语言描述书上源代码

    5. **哈希表** (CuckooHashTable.java): 哈希表是一种基于哈希函数的查找结构,用于实现快速的查找、插入和删除操作。Cuckoo哈希是一种特殊的哈希表设计,通过Cuckoo算法处理冲突,具有较高的空间效率和较低的查找...

    哈希表java实现及简单演示

    哈希表,又称为散列表,是一种数据结构,它通过使用散列函数将键(Key)映射到数组的特定位置来实现快速访问。在Java中,哈希表的实现主要依赖于`java.util.HashMap`类,它是基于哈希表的Map接口实现。在这个Java版...

    一致性hashjava实现

    Ketama一致性哈希算法由Last.fm的工程师开发,其设计目标是优化分布式哈希表的性能,特别是在处理大量小键值对时。它通过引入虚拟节点的概念,提高了哈希空间的分布均匀性,减少了因节点变动导致的数据迁移。 1. **...

    10种java性能优化方案.docx

    - **选择高效的算法和数据结构**:例如,使用哈希表而不是链表进行查找操作。 - **避免不必要的计算**:如文档中提到的,优化算法的关键部分,特别是那些占总运行时间较大比例的部分。 - **利用缓存技术**:通过...

    java描述版数据结构(简单易懂)

    哈希表(Hash Table)是一种通过哈希函数快速定位数据的数据结构,实现了键值对的快速查找。Java中的哈希表主要由`java.util.HashMap`和`java.util.Hashtable`类代表,具有O(1)的平均查找时间复杂度。 六、高级排序...

    uthash开源的hash函数实现

    UTHASH 是一个开源的 C 语言库,提供了一种简单且高效的哈希表实现,用于在 C 代码中快速查找和管理数据结构。这个库的主要功能是提供一个宏定义的集合,可以方便地将结构体转化为哈希表,进而进行添加、删除、查找...

    Java-codes.rar_HASH JAVA_huffman

    在给定的“Java-codes.rar_HASHJAVA_huffman”压缩包中,包含了多个与Java编程相关的示例代码,主要涉及哈夫曼编码(Huffman Coding)、快速排序(Quicksort)、哈希表(Hash)以及一种名为“q_sort”的排序算法。...

    数据结构与算法分析_Java语言描述(第3版)源码

    7. **哈希表**(CuckooHashTable.java, CuckooHashTableClassic.java): 哈希表提供了一种快速查找和插入数据的方法,通过散列函数将键映射到数组的索引。Cuckoo哈希是一种特殊的哈希表实现,使用了Cuckoo算法,当冲突...

    PersistentIdealHashTree-Java实现

    通过以上分析,我们可以看出,PersistentIdealHashTree的Java实现不仅涉及到数据结构的设计和优化,还需要考虑并发编程中的线程安全问题。理解并掌握这种数据结构的实现原理,对于提升Java程序员在大数据处理和并发...

    数据结构与算法分析-java

    本书由Mark Allen Weiss所著,目的在于通过Java语言来分析和探讨数据结构及算法的原理与应用。根据提供的部分目录内容,本书共分为12个章节,涵盖了数据结构与算法分析的各个重要领域。 在第1章“引言”中,作者...

    数据结构与算法分析(Java版)

    ### 数据结构与算法分析(Java版)核心知识点详解 #### 一、概述 《数据结构与算法分析(Java版)》是由Robert Lafore编写的一本详细介绍数据结构与算法原理及其实现的书籍。本书旨在帮助读者理解如何通过数据结构...

    Java数据结构与算法书中源码

    7. **哈希表** - `CuckooHashTable.java`和`CuckooHashTableClassic.java`涉及到的是Cuckoo哈希,这是一种解决哈希冲突的策略。哈希表是通过键值对进行快速查找的数据结构,Cuckoo哈希通过交替插入位置来解决冲突,...

    Hash map 哈希表

    哈希表,也被称为Hash Map,是计算机科学中一种高效的数据结构,用于存储键值对。它通过一种称为哈希函数的过程将键映射到数组的特定位置,从而实现快速的查找、插入和删除操作。在哈希表中,查找时间通常接近常数...

Global site tag (gtag.js) - Google Analytics