在一个类中重写hashCode()和equals()

package Date_pacage.hash;

public class Student {
private int grade;
private int cls;
String firstName;
String lastName; Student(int grade, int cls, String firstName, String lastName){
this.grade = grade;
this.cls = cls;
this.firstName = firstName;
this.lastName = lastName;
} //如果没有覆盖这个方法,java会自动给Student这个类的每个对象分配一个hashCode,
//这个自动分配的hashCode是根据对象的地址来分配的
@Override
public int hashCode() { int B = 31; int hash = 0;
hash = hash * B + grade;
hash = hash * B + cls;
//字符串不区分大小写
hash = hash * B + firstName.hashCode();
hash = hash * B + lastName.hashCode(); return hash;
} @Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if(o == null) {
return false;
}
if(getClass() != o.getClass()) {
return false;
}
Student another = (Student)o;
return this.grade == another.grade &&
this.cls == another.cls &&
this.firstName.toLowerCase().equals(another.firstName.toLowerCase()) &&
this.lastName.toLowerCase().equals(another.lastName.toLowerCase()); }
}

实现一个HashTable:

package Date_pacage.hash;

import java.util.TreeMap;

//哈希冲突的处理:链地址法
//哈希表的动态空间处理:平均每个地址承载的元素过多一定程度,即扩容
// N/M >= upperTol
//平均每个地址承载的元素过少一定程度,即缩容
//N/M <= lowerTol
public class HashTable<K, V> { private static final int upperTol = 10;
private static final int lowerTol = 2;
private static final int initCapacity = 7;
//这里要求K extends Comparable
private TreeMap<K, V> hashtable[];
//TreeMap[]:这里表达的是一个存储TreeMap类型的数组!
private int M;//hashTable中有M个位置
private int size;//整个哈希表中元素的个数,就是N public HashTable(int M) {
this.M = M;
size = 0;
//哈希表的底层用了TreeMap,那么hashMap是怎么实现的
//Hashtable与HashMap类似,不同的是:它不允许记录的键或者值为空;
     //它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢。
hashtable = new TreeMap[M];
for(int i = 0 ; i < M ; i ++) {
hashtable[i] = new TreeMap<>();
}
} public HashTable() {
this(initCapacity);
} private int hash(K key) {
return (key.hashCode() & 0x7fffffff) % M;
} public int getSize() {
return size;
} public void add(K key, V value) {
//如果有两个字符串的哈希值相同,他们就被分配到一个TreeMap中去
//在将数据传入TreeMap时使用(key, value),
//key是字符串,value是字符串出现的个数
TreeMap<K, V> map = hashtable[hash(key)];
if(map.containsKey(key)) {
map.put(key, value);
}else {
map.put(key, value);
size ++;
if(size >= upperTol * M) {
resize(2 * M);
}
}
} public V remove(K key) {
TreeMap<K, V> map = hashtable[hash(key)];
V ret = null;
if(map.containsKey(key)) {
ret = map.remove(key);
size --;
if(size < lowerTol * M && M / 2 >= initCapacity) {
resize(M / 2);
}
}
return ret;
} public void set(K key, V value) {
TreeMap<K, V> map = hashtable[hash(key)];
if(!map.containsKey(key)) {
throw new IllegalArgumentException(key + "doesn't exist!");
}
map.put(key, value);
} public boolean contains(K key) {
return hashtable[hash(key)].containsKey(key);
} public V get(K key) {
return hashtable[hash(key)].get(key);
} private void resize(int newM) {
TreeMap<K, V>[] newHashTable = new TreeMap[newM];
for(int i = 0 ; i < newM ; i ++) {
newHashTable[i] = new TreeMap<>();
} int oldM = M;
this.M = newM;
for(int i = 0 ; i < oldM ; i ++) {
TreeMap<K, V> map = hashtable[i];
for(K key : map.keySet()) {
newHashTable[hash(key)].put(key, map.get(key));
}
}
this.hashtable = newHashTable;
}
}

hashMap中的hash方法:

作用:是返回输入对象在hashMap数组中的下标值

具体做法:

原始想法是根据hashcode()得到的散列值^数组长度,得到所在数组下标值,缺点是碰撞严重,只用到了散列值中数组长度的低位信息。

优化想法:增加一个扰动函数,也就是

(var1 = var0.hashCode()) ^ var1 >>> 16
相当于是增加了返回值的信息量,扰动之后的值^数组长度,这时得到的数组下标值碰撞次数减少了很多

java——哈希表 HashTable的更多相关文章

  1. Java中哈希表(Hashtable)是如何实现的

    Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...

  2. 哈希表(hashtable)的javascript简单实现

    javascript中没有像c#,java那样的哈希表(hashtable)的实现.在js中,object属性的实现就是hash表,因此只要在object上封装点方法,简单的使用obejct管理属性的 ...

  3. Java哈希表入门

    Java哈希表(Hash Table) 最近做题经常用到哈希表来进行快速查询,遂记录Java是如何实现哈希表的.这里只简单讲一下利用Map和HashMap实现哈希表. 首先,什么是Map和HashMa ...

  4. 使用java实现希表的基础功能

    用java代码完成哈希表数据结构的简单实现, 以公司雇员的添加修改作为模拟实例 具体代码如下: package com.seizedays.hashtable; import java.util.Sc ...

  5. 哈希表(Hashtable)简述

    一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...

  6. c/c++ 哈希表 hashtable

    c/c++ 哈希表 hashtable 概念:用key去查找value 实现hash函数有很多方法,本文用除留余数法. 除留余数法的概念: 取一个固定的基数的余数,注意不能用偶数,用偶数的话,分布会不 ...

  7. C#中哈希表(HashTable)的用法详解以及和Dictionary比较

    1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对, ...

  8. 转 C#中哈希表(HashTable)的用法详解

    看了一遍有关哈希表的文字,作者总结的真是不错 .收藏起来 1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提 ...

  9. 哈希表hashTable的Java设计

    1:哈希表的概念 2:设计原理 3:哈希表的Java设计

随机推荐

  1. Switch/Case 的穿透性

    /*键盘录入1到12 ,对应输出该月份对应的季节 .如果输入的不是1到12,输出提示信息:您输入的数据有误. PS: 春季:3,4,5月份 夏季: 6,7,8月份 秋季: 9,10,11月份 冬季:1 ...

  2. 算法Sedgewick第四版-第1章基础-012一用stack实现输出一个数的二进制形式

    @Test public void e1_3_5() { Stack<Integer> stack = new Stack<Integer>(); int N = 7; whi ...

  3. Entity Framework Tutorial Basics(34):Table-Valued Function

    Table-Valued Function in Entity Framework 5.0 Entity Framework 5.0 supports Table-valued functions o ...

  4. PartyLocation的Post请求问题---debug

    这里,遇到了一个debug: @Override public void setPrimaryPartyLocation(PartyLocation partyLocation) { if (!get ...

  5. WordCount优化-第四周小组作业

    一.基本功能 GITHUB项目地址:https://github.com/LongtermPartner/ExtendWordCount PSP表格填写: PSP2.1 PSP阶段 预估耗时 (分钟) ...

  6. AttributeError: 'module' object has no attribute 'gfile'

    While running TensorFlow's classify_image, getting AttributeError: 'module' object has no attribute ...

  7. HTML5与CSS3基础教程(第7版) 高清PDF扫描版​

    HTML5与CSS3基础教程(第7版)试读不仅介绍了文本.图像.链接.列表.表格.表单.多媒体等网页元素,也介绍了如何为网页设计结构.布局,添加动态效果.格式化等形式,此外还涉及调试和发布.聚合和吸引 ...

  8. Oauth Client Credentials Grant

    http://www.cnblogs.com/dudu/p/4569857.html OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft. ...

  9. 加快 hive 查询的 5 种方法

    1. 使用 Tez set hive.execution.engine=tez; 2. 使用 ORCFILE.当有多个表 join 时,使用 ORCFile 进行存储,会显著地提高速度. CREATE ...

  10. Javascript之入门篇(一)

    上一篇学习了什么是JavaScript语言及其作用和特有的特点等,本篇将详细介绍JavaScript一些入门使用方式. 对于初学者来讲,由于JavaScript是嵌入到HTML页面里面的,首先创建一张 ...