哈希表是基于数组来实现的一种数据结构,提高了快速的插入和查找操作
1.直接将关键字作为索引(关键字是数字类型)
2.将单词转换成索引(关键字是string类型)
2.1将字母转换成ASCII码,然后进行相加
存在风险: 比如: key1=abc , ,key2=bbb ;key1和key2通过将字母转化成ascii码后相加的值相等
2.2幂的连乘
127^2 + 227^1 + 3*27^0 … (27代表26个字母加一个空格 , 1代表第一个字母,2代表第二个字母…)
存在风险: 1.数组索引太大,造成空间浪费 ;
2.索引越界(大于int / long类型的界限)
2.3压缩可选值
把幂连乘的结果对数组长度取模,再把取模后的结果当成索引存进数组中
使用BigInteger类型代替int/long类型,避免幂连乘的结果越界
存在风险: 1.取模后会出现重复值,导致存进去数组的数据被覆盖掉 ;
冲突: 不能保证每个单词都映射到数组的空白单元
解决办法:
1.开放地址法
2.链地址法
1.1创建JavaBean
public class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1.2创建HashTable
public class HashTable {
//数组
private Person[] arr;
//构造
public HashTable() {
arr = new Person[10];
}
public HashTable(int size){
arr = new Person[size];
}
//插入数据
public void insert(Person person){
//将关键字 id 作为数组的索引
arr[person.getId()] = person;
}
//查找数据
public Person find(int id){
return arr[id];
}
}
1.3测试
public class Test {
public static void main(String[] args) {
HashTable hashTable = new HashTable();
//插入数据
hashTable.insert(new Person(1,"张三"));
hashTable.insert(new Person(2,"李四"));
hashTable.insert(new Person(3,"王五"));
//查找
Person person = hashTable.find(2);
System.out.println(person.getName());
}
}
2.1创建JavaBean
public class Person {
private String key;
private String name;
public Person(String key, String name) {
this.key = key;
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.2创建HashTable
public class HashTable {
//数组
private Person[] arr;
//构造
public HashTable() {
arr = new Person[10];
}
public HashTable(int size){
arr = new Person[size];
}
//插入数据
public void insert(Person person){
//将关键字key 进行hash化后进行求和再作为索引
arr[hashCode(person.getKey())] = person;
}
//查找数据
public Person find(String key){
return arr[hashCode(key)];
}
//字符串转化成ASCII码,并且进行相加
public int hashCode(String key){
int hashCode = 0;
for (int i = key.length()-1;i>= 0 ; i--){
int value = key.charAt(i) - 96;
hashCode += value;
}
return hashCode;
}
}
2.3测试
public class Test {
public static void main(String[] args) {
HashTable hashTable = new HashTable();
//插入数据
hashTable.insert(new Person("abc","张三"));
hashTable.insert(new Person("bcd","李四"));
hashTable.insert(new Person("bbb","王五"));
//查找
Person person = hashTable.find("abc"); //王五
System.out.println(person.getName());
person = hashTable.find("bbb"); //王五
System.out.println(person.getName());
//风险: abc 的hashCode = bbb 的hashCode
}
}
3.1创建JavaBean
public class Person {
private String key;
private String name;
public Person(String key, String name) {
this.key = key;
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.2创建HashTable
public class HashTable {
//数组
private Person[] arr;
//构造
public HashTable() {
arr = new Person[10000];
}
public HashTable(int size){
arr = new Person[size];
}
//插入数据
public void insert(Person person){
//将关键字key 进行hash化后进行求和再作为索引
arr[hashCode(person.getKey())] = person;
}
//查找数据
public Person find(String key){
return arr[hashCode(key)];
}
//字符串转化成ASCII码,并且进行幂的连乘
public int hashCode(String key){
int hashCode = 0;
for (int i = key.length()-1;i>= 0 ; i--){
int value = key.charAt(i) - 96;
int sum = value*27^(key.length() - value);
hashCode += sum;
}
return hashCode;
}
}
3.3测试
public class Test {
public static void main(String[] args) {
HashTable hashTable = new HashTable();
//插入数据
hashTable.insert(new Person("abc","张三"));
hashTable.insert(new Person("bcd","李四"));
hashTable.insert(new Person("bbb","王五"));
//查找
Person person = hashTable.find("abc"); //张三
System.out.println(person.getName());
person = hashTable.find("bbb"); //王五
System.out.println(person.getName());
//风险: 索引数值太大
}
}
4.1创建JavaBean
public class Person {
private String key;
private String name;
public Person(String key, String name) {
this.key = key;
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4.2创建HashTable
import java.math.BigInteger;
public class HashTable {
//数组
private Person[] arr;
//构造
public HashTable() {
arr = new Person[10];
}
public HashTable(int size){
arr = new Person[size];
}
//插入数据
public void insert(Person person){
//将关键字key 进行hash化后进行求和再作为索引
arr[hashCode(person.getKey())] = person;
}
//查找数据
public Person find(String key){
return arr[hashCode(key)];
}
//字符串转化成ASCII码,并且进行幂的连乘,最后取模再返回
//使用 BigInteger 类型代替int类型
public int hashCode(String key){
BigInteger hashCode = new BigInteger("0");
BigInteger pow = new BigInteger("1");
for (int i = key.length()-1;i>= 0 ; i--){
BigInteger value = new BigInteger(String.valueOf(key.charAt(i) - 96));
hashCode = hashCode.add(value.multiply(pow));
pow = pow.multiply(new BigInteger("27"));
}
//取模后再转成 int 类型返回
return hashCode.mod(new BigInteger(String.valueOf(arr.length))).intValue();
}
}
4.3测试
public class Test {
public static void main(String[] args) {
HashTable hashTable = new HashTable();
//插入数据
hashTable.insert(new Person("abcdefghijklmn","张三"));
hashTable.insert(new Person("bcd","李四"));
hashTable.insert(new Person("ccc","王五"));
//查找
Person person = hashTable.find("abcdefghijklmn"); //张三
System.out.println(person.getName());
person = hashTable.find("bcd"); //李四
System.out.println(person.getName());
//风险: 压缩空间后可能出现重复索引值
}
}