在一个类中重写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. 安装visual_Paradigm,时序图的应用

    此安装包已经上传到sunny的百度网盘. 删除,即,右击别的地方,然后,选择delete即可. 拖箭头,拖到某个实体上,再松开,会自动连线. 很好的一款画图工具.

  2. 解决SQL Server [Suspect]

    昨天因断电,数据库 "DatabaseName" 被标记为 [Suspect],被质疑了? Search 后,以下方案最终解决了问题. USE [master] GO ALTER ...

  3. java 的exception throw try catch

    import java.util.*; public class MyException extends Exception { private static final Exception Exce ...

  4. Javascript-DOM笔记

    参考 javascript原生dom操作方法 JavaScript原生的dom操作方法 第一类:节点查找相关方法和属性 document/父节点.getElementById()document/父节 ...

  5. JS中setTimeout()的用法详解

    1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTi ...

  6. netty下载源码并导入idea

    netty源码导入eclipse会有一些兼容性问题,网上有解决方案,官方推荐idea,故此用idea. 拷贝git地址:https://github.com/netty/netty.git 使用git ...

  7. mysql在linux下的安装与优化

    mysql5.6 http://www.cnblogs.com/bookwed/p/5896619.html mysql5.7 http://blog.csdn.net/wb96a1007/artic ...

  8. Copy拷贝

    前言 copy:需要先实现 NSCopying 协议,创建的是不可变副本. mutableCopy:需要实现 NSMutableCopying 协议,创建的是可变副本. 浅拷贝:指针拷贝,源对象和副本 ...

  9. Swift3.0 UICollectionView简单使用

    感觉swift各版本语法改动太大,储备着吧

  10. poj1681(枚举or高斯消元解mod2方程组)

    题目链接: http://poj.org/problem?id=1681 题意: 有一个包含 n * n 个方格的正方形, w 表示其所在位置为白色, y 表示其所在位置为黄色. 对 (i, j) 位 ...