在一个类中重写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. 利用脚本,一键设置java环境变量(默认安装路径)

    Windows一键设置Java环境变量 右击以管理员方式运行,注意自行更改JAVA_HOME目录文件安装目录. JDKSetting.bat @echo off color 0a echo.----- ...

  2. Python Matplotlib.plot Update image Questions

    1. 最近在测试一款设备,采集了一些设备后需要一帧一帧显示图像,经常使用Python,所以选用了Matplotlib进行图像操作 数据结构: timesatamp polar_distance hor ...

  3. VSTO的简单用法

    一直听说vsto这个名词,还真不知道什么意思,今天了解了一下,原来他的全程是Visual Studio Tools For Office,说他是VBA的替身(VBA俺也不是很懂),刚才上网查询做了个例 ...

  4. spring、spring mvc以及IOC的阅读

    spring vs spring-mvc spring是应用级框架 spring mvc只是一个mvc框架 spring现在包含很多子模块,我们用的最多的是依赖注入. spring模块可分为以下: C ...

  5. PL/0语言词法分析器

    前言:关于词法分析的基础知识的介绍可以看一下这篇博客,我再累述估计也不会有这篇讲的清楚QAQ. https://www.cnblogs.com/yanlingyin/archive/2012/04/1 ...

  6. 基于vue框架项目开发过程中遇到的问题总结(二)

    1.mouseup事件丢失 查看了网上资料,造成mouseup事件丢失有两种原因: (1)触发了浏览器的drag事件 (2)由于鼠标离开了操作的区域,触发了mouseleave事件导致mouseup丢 ...

  7. Kibana error " Fielddata is disabled on text fields by default. Set fielddata=true on [publisher] ..."

    Reason of this error:Fielddata can consume a lot of heap space, especially when loading high cardina ...

  8. kuangbin专题十六 KMP&&扩展KMP HDU3294 Girls' research

    One day, sailormoon girls are so delighted that they intend to research about palindromic strings. O ...

  9. 洛谷P3507 [POI2010]GRA-The Minima Game

    题目描述 Alice and Bob learned the minima game, which they like very much, recently. The rules of the ga ...

  10. Qt 学习之路 2(1):序

    https://www.devbean.net/category/qt-study-road-2/page/10 原来开过QT学习之路1, 很棒, 再翻阅时已经没有了. 所以这次把看过的记录下来 Ho ...