Lecture 20: Hash Tables

10/12/2020

Data Indexed Arrays

Limits of Search Tree Based Sets

Using Data as an Index

public class DataIndexedIntegerSet { private boolean[] present; public DataIndexedIntegerSet() { present = new boolean[2000000000]; } public add(int i) { present[i] = true; } public contains(int i) { return present[i]; } }

DataIndexedEnglishWordSet

Generalizing the DataIndexedIntegerSet Idea

Avoiding Collisions

THe Decimal Number System vs. Our Own System for Strings

Uniqueness

public class DataIndexedEnglishWordSet { private boolean[] present; public DataIndexedEnglishWordSet() { present = new boolean[2000000000]; } public add(String s) { present[englishToInt(s)] = true; } public contains(String s) { return present[englishToInt(s)]; } }

DataIndexedStringSet

DataIndexedStringSet

ASCII Characters

Implementing asciiToInt

Going Beyond ASCII

Example: Computing Unique Representations of Chinese

Integer Overflow and Hash Codes

Major Problem: Integer Overflow

Consequence of Overflow: Collisions

Hash Codes and the Pigeonhole Principle

Two Fundamental Challenges

Hash Tables: Handling Collisions

Resolving Ambiguity

The Separate Chaining Data Indexed Array

Separate Chaining Performance

Saving Memory Using Separate Chaining

The Hash Table

Hash Table Performance

Hash Table Runtime

Improving the Hash Table

Hash Table Runtime

Resizing Hash Table Runtime

Has Table Runtime

Regarding Even Distribution

Hash Tables in Java

The Ubiquity of Hash Tables

Objects

Examples of Real Java HashCodes

"a".hashCode() // 97 "bee".hashCode() // 97410

Using Negative hash codes

-1 % 4 // -1 Math.floorMod(-1, 4) // 3

Hash Tables in Java

Two Important Warnings When Using HashMaps/HashSets

Good HashCodes

What Makes a good hashCode()?

Hashbrowns and Hash Codes

Example hasCode Function

@Override public int hasCode() { int h = cachedHashValue; if (h == 0 && this.length() > 0) { for (int i = 0; i < this.length; i++) { h = 31 * h + this.charAt(i); } cachedHasValue = h; } return h; }

Example: Choosing a Base

Typical Base

Hashbrowns and Hash Codes

Example: Hashing a Collection

@Override public int hashCode() { int hashCode = 1; for (Object o : this) { hashCode = hashCode * 31; // elevate/smear the current hash code hashCode = hashCode + o.hashCode(); // add new item's hash code } return hashCode }

Example: Hashing a Recursive Data Structure

@Override public int hashCode() { if (this.value == null) { return 0; } return this.value.hashCode() + 31 * this.left.hashCode() + 31 * 31 * this.right.hashCode(); }

Summary

Hash Tables in Java