七,用代码来验证自己写的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环境下的各种哈希计算工具和示例,帮助开发者进行数据校验、安全存储、性能优化等工作。通过理解和应用这些哈希计算技术,可以提升软件的安全性和效率。
这本书通过使用Java编程语言,向读者展示了如何设计、实现和分析一系列关键的数据结构和算法,以解决实际问题。书中的源代码是理解理论知识与实际应用之间的桥梁,为学习者提供了实践操作的机会。 首先,我们来看...
通过上述分析,我们可以看到Blizzard的Hash表实现不仅体现了对散列技术的深刻理解,而且还展示了如何利用多个散列值来进一步提高Hash表的性能和准确性。这种技术尤其适用于处理大量数据的情况,能够显著减少冲突的...
《数据结构与算法分析_Java语言描述(第3版)》是一本深入探讨数据结构和算法分析的专业书籍,它以Java编程语言为载体,详细阐述了如何高效地组织和操作大量数据,以及如何评估和比较不同算法的性能。这本书不仅涵盖了...
在Java编程中,Map接口是用于存储键值对的数据结构,而Java提供了多种Map的实现,包括TreeMap、HashMap和ConcurrentSkipListMap。本文主要比较了这三种Map的性能,尤其是在插入和查找操作上的效率。 1. **TreeMap**...
本课件“数据结构 课件java版本”是基于Java编程语言来讲解这一主题的,旨在帮助学生和开发者深入理解数据结构的基本概念,并掌握用Java实现这些数据结构的方法。 在Java中,数据结构主要分为以下几类: 1. **数组...
5. **哈希表** (CuckooHashTable.java): 哈希表是一种基于哈希函数的查找结构,用于实现快速的查找、插入和删除操作。Cuckoo哈希是一种特殊的哈希表设计,通过Cuckoo算法处理冲突,具有较高的空间效率和较低的查找...
哈希表,又称为散列表,是一种数据结构,它通过使用散列函数将键(Key)映射到数组的特定位置来实现快速访问。在Java中,哈希表的实现主要依赖于`java.util.HashMap`类,它是基于哈希表的Map接口实现。在这个Java版...
Ketama一致性哈希算法由Last.fm的工程师开发,其设计目标是优化分布式哈希表的性能,特别是在处理大量小键值对时。它通过引入虚拟节点的概念,提高了哈希空间的分布均匀性,减少了因节点变动导致的数据迁移。 1. **...
- **选择高效的算法和数据结构**:例如,使用哈希表而不是链表进行查找操作。 - **避免不必要的计算**:如文档中提到的,优化算法的关键部分,特别是那些占总运行时间较大比例的部分。 - **利用缓存技术**:通过...
哈希表(Hash Table)是一种通过哈希函数快速定位数据的数据结构,实现了键值对的快速查找。Java中的哈希表主要由`java.util.HashMap`和`java.util.Hashtable`类代表,具有O(1)的平均查找时间复杂度。 六、高级排序...
UTHASH 是一个开源的 C 语言库,提供了一种简单且高效的哈希表实现,用于在 C 代码中快速查找和管理数据结构。这个库的主要功能是提供一个宏定义的集合,可以方便地将结构体转化为哈希表,进而进行添加、删除、查找...
在给定的“Java-codes.rar_HASHJAVA_huffman”压缩包中,包含了多个与Java编程相关的示例代码,主要涉及哈夫曼编码(Huffman Coding)、快速排序(Quicksort)、哈希表(Hash)以及一种名为“q_sort”的排序算法。...
7. **哈希表**(CuckooHashTable.java, CuckooHashTableClassic.java): 哈希表提供了一种快速查找和插入数据的方法,通过散列函数将键映射到数组的索引。Cuckoo哈希是一种特殊的哈希表实现,使用了Cuckoo算法,当冲突...
通过以上分析,我们可以看出,PersistentIdealHashTree的Java实现不仅涉及到数据结构的设计和优化,还需要考虑并发编程中的线程安全问题。理解并掌握这种数据结构的实现原理,对于提升Java程序员在大数据处理和并发...
本书由Mark Allen Weiss所著,目的在于通过Java语言来分析和探讨数据结构及算法的原理与应用。根据提供的部分目录内容,本书共分为12个章节,涵盖了数据结构与算法分析的各个重要领域。 在第1章“引言”中,作者...
### 数据结构与算法分析(Java版)核心知识点详解 #### 一、概述 《数据结构与算法分析(Java版)》是由Robert Lafore编写的一本详细介绍数据结构与算法原理及其实现的书籍。本书旨在帮助读者理解如何通过数据结构...
7. **哈希表** - `CuckooHashTable.java`和`CuckooHashTableClassic.java`涉及到的是Cuckoo哈希,这是一种解决哈希冲突的策略。哈希表是通过键值对进行快速查找的数据结构,Cuckoo哈希通过交替插入位置来解决冲突,...
哈希表,也被称为Hash Map,是计算机科学中一种高效的数据结构,用于存储键值对。它通过一种称为哈希函数的过程将键映射到数组的特定位置,从而实现快速的查找、插入和删除操作。在哈希表中,查找时间通常接近常数...