Hash Tables
1
Lecture 26
CS61B, Fall 2025 @ UC Berkeley
Josh Hug and Peyrin Kao
Motivation, Set Implementations
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
2
Sets
We’ve now seen several implementations of the Set (or Map) ADT.
3
Set
ArraySet
BST
2-3 Tree
LLRB
Map
| contains(x) | add(x) | Notes |
ArraySet | Θ(N) | Θ(N) | |
BST | Θ(N) | Θ(N) | Random trees are Θ(log N). |
2-3 Tree | Θ(log N) | Θ(log N) | Beautiful idea. Very hard to implement. |
LLRB | Θ(log N) | Θ(log N) | Maintains bijection with 2-3 tree. Hard to implement. |
Worst case runtimes
Limits of Search Tree Based Sets
Our search tree based sets require items to be comparable.
Our search tree sets have excellent performance, but could maybe be better?
Today we’ll see the answer to both of the questions above is yes.
4
ArrayOfListsSet
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
5
Back to LinkedList
Suppose we have a LinkedListSet<Integer>. Let’s assume there is no specific order.
6
size
contains
add
iterator
9
4
3
5
1
8
2
front
7
size
Improvements
We considered two different ways we could improve the data structure below.
The two approaches above required the data to be in sorted order.
7
size
contains
add
iterator
9
4
3
5
1
8
2
front
7
size
Key Idea: Multiple Lists
What if we split our list into two lists, one containing the even items, and one containing the odd items?
8
9
5
3
1
4
2
8
Even More Lists
Suppose we now have 10 lists.
Also: How much faster will this new approach be relative to having a single list.
9
0
1
2
3
4
5
6
7
8
9
Even More Lists
Suppose we now have 10 lists.
Here: % means modulus.
10
0
1
2
3
4
5
6
7
8
9
3
13
4
5
6
7
8
9
10
11
12
14
15
ArrayOfListsSet
Below is a picture of our ArrayOfListsSet for M = 10.
If we have N items that are evenly distributed, length of each list is N/M.
11
0
1
2
3
4
5
6
7
8
9
88
0
10
3719
1034854400
% 10
0
reduce
index
ArrayOfListsSet
4178
44
9
1034854400
Each integer gets reduced into an index.
Buckets and Reduction Functions
For this type of data structure, each list is sometimes called a “bucket”.
12
0
1
2
3
4
5
6
7
8
9
88
0
10
3719
1034854400
% 10
0
reduce
index
ArrayOfListsSet
4178
44
9
1034854400
Each integer gets reduced into an index.
DynamicArrayOf ListsSet
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
13
The Logical Extreme
Suppose we have as many lists as there are integers.
Issues?
14
0
1
2
3
4
5
6
7
8
9
3
6
1
...
99384982
99384983
99384983
...
The Logical Extreme
Suppose we have as many lists as there are integers.
This approach would be wasteful.
15
0
1
2
3
4
5
6
7
8
9
3
6
1
...
99384982
99384983
99384983
...
Finding a Happy Medium
We’ve observed a tradeoff between runtime and space usage:
16
Finding a Happy Medium
We’ve observed a tradeoff between runtime and space usage:
What M should we pick?
17
Finding a Happy Medium (Your Answer)
We’ve observed a tradeoff between runtime and space usage:
What M should we pick?
18
Finding a Happy Medium (My Answer)
We’ve observed a tradeoff between runtime and space usage:
What M should we pick?
We should start with an M that is small, and let M get larger as N gets larger.
19
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
20
0
1
2
3
N = 0 M = 4 N / M = 0
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
21
0
1
2
3
N = 1 M = 4 N / M = 0.25
7
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
22
0
1
2
3
N = 2 M = 4 N / M = 0.5
7
16
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
23
0
1
2
3
N = 3 M = 4 N / M = 0.75
7
16
3
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
24
0
1
2
3
N = 4 M = 4 N / M = 1
7
16
3
11
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
25
0
1
2
3
N = 5 M = 4 N / M = 1.25
7
16
3
11
20
Hash Table Resizing Example
Suppose we set a rule that when N/M is ≥ 1.5, we double M.
26
0
1
2
3
N = 6 M = 4 N / M = 1.5
N/M is too large. Time to double!
7
16
3
11
20
13
Hash Table Resizing Example
When N/M is ≥ 1.5, then double M.
27
0
1
2
3
N = 6 M = 4 N / M = 1.5
N/M is too large. Time to double!
?
?
?
0
1
2
3
4
5
6
7
?
?
?
?
?
7
16
11
20
13
3
Hash Table Resizing Example
When N/M is ≥ 1.5, then double M.
28
0
1
2
3
N = 6 M = 4 N / M = 1.5
N/M is too large. Time to double!
0
1
2
3
4
5
6
7
N = 6 M = 8 N / M = 0.75
7
16
11
20
13
3
16
3
11
20
13
7
DynamicArrayOfListsSet
The data structure we just built might be called a DynamicArrayOfListsSet.
If we have N items that are evenly distributed, length of each list is ~N/M.
We’ll think more carefully about runtime later.
29
1034854400
% 6
2
reduce
index
0
1
2
3
4
5
146
0
6
2133
DynamicArrayOfListsSet
103485440
46
9
Each integer gets reduced into an index.
lowercase strings
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
30
Goal: Storing Strings
The data structure we have so far is great for storing integers.
31
Storing the Word cat
Suppose we want to add(“cat”)
The key question:
What are some issues with this approach?
32
Storing the Word cat (your answer)
Suppose we want to add(“cat”)
The key question:
What are some issues with this approach?
33
Storing the Word cat (my answer)
Suppose we want to add(“cat”)
The key question:
What are some issues with this approach?
34
Finding a Way to Store the Word cat
Suppose we want to add(“cat”)
The key question:
What is another idea? Assume for now we’re dealing with only lower case letters in English.
35
Finding a Way to Store the Word cat (Your Answer)
Suppose we want to add(“cat”)
The key question:
What is another idea? Assume for now we’re dealing with only lower case letters in English.
36
Finding a Way to Store the Word cat (My Answer)
Suppose we want to add(“cat”)
The key question:
What is another idea? Assume for now we’re dealing with only lower case letters in English.
37
Treating cat as a Base 26 Number
Use all digits by multiplying each by a power of 26.
Why this specific pattern?
38
The Decimal Number System vs. My System for Strings
In the decimal number system, we have 10 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Want numbers larger than 9? Use a sequence of digits.
Example: 7091 in base 10
Our system for strings is almost the same, but with letters.
39
Test Your Understanding (yellkey this)
Convert the word “bee” into a number by using our “powers of 26” strategy.
Reminder: cat26 = (3 x 262) + (1 x 261) + (20 x 260) = 207410
Hint: ‘b’ is letter 2, and ‘e’ is letter 5.
40
Test Your Understanding
Convert the word “bee” into a number by using our “powers of 26” strategy.
Reminder: cat26 = (3 x 262) + (1 x 261) + (20 x 260) = 207410
Hint: ‘b’ is letter 2, and ‘e’ is letter 5.
41
Uniqueness
As long as we pick a base ≥ 26, this algorithm is guaranteed to give each lowercase English word a unique number!
42
DynamicArrayOfLinkedLists with Integerization
We’ve now extended our DynamicArrayOfLinkedLists to handle strings.
43
0
1
2
3
4
5
6
cats
map
go
fish
cat
lowerCaseToInt
2074
% 7
1
data
integer
Integerization Function
reduce
index
DynamicArrayOfLinkedLists
horse
cat
ball
sad
Implementing englishToInt (optional)
Optional exercise: Try to write a function englishToInt that can convert English strings to integers by adding characters scaled by powers of 26.
Examples:
44
Implementing englishToInt (optional) (solution)
45
/** Converts ith character of String to a letter number.� * e.g. 'a' -> 1, 'b' -> 2, 'z' -> 26 */
public static int letterNum(String s, int i) {
int ithChar = s.charAt(i);
if ((ithChar < 'a') || (ithChar > 'z'))
{ throw new IllegalArgumentException(); }
return ithChar - 'a' + 1;
}
public static int englishToInt(String s) {
int intRep = 0;
for (int i = 0; i < s.length(); i += 1) {
intRep = intRep * 26;
intRep = intRep + letterNum(s, i);
}
return intRep;
}
Integer Overflow
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
46
DataIndexedStringSet
Using only lowercase English characters is too restrictive.
Suppose we wanted a unique integer for each possible such string.
Someone has already done this.
47
ASCII Characters
The most basic character set used by most computers is ASCII format.
48
biggest value is 126
DataIndexedStringSet
Maximum possible value for english-only text including punctuation is 126, so can use 126 as our base in order to ensure unique values for all possible strings.
Examples:
=101,809,233
= 203,178,213
49
Implementing asciiToInt
Below is a simple formula which converts a String to an integer.
What if we want to use characters beyond ASCII?
50
public static int asciiToInt(String s) {
int intRep = 0;
for (int i = 0; i < s.length(); i += 1) {
intRep = intRep * 126;
intRep = intRep + s.charAt(i);
}
return intRep;
}
Going Beyond ASCII
chars in Java also support character sets for other languages and symbols.
51
Example: Computing Unique Representations of Chinese
The largest possible value for Chinese characters is 40,959*, so we’d need to use this as our base if we want to have a unique representation for all possible strings of Chinese characters.
Example:
52
守门呗
守门员
守门呙
39,3120,2486,9367
39,3120,2486,9368
39,3120,2486,9369
...
...
*If you’re curious, the last character is:
...
...
Hash Codes
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
53
Finitely Many Integers
So far, we’ve tried to map any possible string to a unique integer.
That is, we tried to map 守门员 as a base 40959 number, yielding 39,312,024,869,368, but this number doesn’t exist in Java as an int.
�Note: Other programming languages do not have finitely many integers. Python, for example, allows an integer to take on any value.
54
What Happens in Practice: Integer Overflow
In Java, the largest possible integer is 2,147,483,647.
55
int x = 2147483647;
System.out.println(x);
System.out.println(x + 1);
jug ~/Dropbox/61b/lec/hashing
$ javac BiggestPlusOne.java
$ java BiggestPlusOne
2147483647
-2147483648
Consequence of Overflow
Because Java has a maximum integer, we won’t get the numbers we expect!
56
Hash Codes
The official term for the number we’re computing is “hash code”.
That is, our integerization function is a “hash code” because the set we’re projected onto is fixed.
57
The Hash Table
A DynamicArrayOfLists with a finite integerization function is called a hash table.
58
0
1
2
3
4
5
6
7
8
9
bee
hug
抱抱
están
抱抱
hashCode()
1034854400
% 10
0
data
hash code
hash function
reduce
index
hash table
dog
الطبيعة
शानदार
포옹
In Java there’s a caveat here. Will revisit later.
守门员
The Hash Table
Note, there are other versions of hash tables out there.
59
0
1
2
3
4
5
6
7
8
9
bee
hug
抱抱
están
抱抱
hashCode()
1034854400
% 10
0
data
hash code
hash function
reduce
index
hash table
dog
الطبيعة
शानदार
포옹
In Java there’s a caveat here. Will revisit later.
守门员
Hash Tables in Java
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
60
The Ubiquity of Hash Tables
Hash tables are the most popular implementation for sets and maps.
In Java, implemented as java.util.HashMap and java.util.HashSet.
61
Object Methods
All classes are hyponyms of Object.
Default implementation of hashCode returns memory address.
62
Won’t discuss or use in 61B.
From earlier in class.
This is where Java implements hash codes.
Hash Codes in Java
Java’s actual hashCode function for Strings below (code cleaned up slightly):
Due to overflow, multiple strings have the same hashcode, e.g. the two calls below both return 23,729,400.
63
public int hashCode(String s) {
int intRep = 0;
for (int i = 0; i < s.length(); i += 1) {
intRep = intRep * 31;
intRep = intRep + s.charAt(i);
}
return intRep;
}
More examples of Real Java HashCodes for Strings
64
System.out.println("a".hashCode());
System.out.println("bee".hashCode());
System.out.println("포옹".hashCode());
System.out.println("kamala lifefully".hashCode());
System.out.println("đậu hũ".hashCode());
jug ~/Dropbox/61b/lec/hashing
$ java JavaHashCodeExamples
97
97410
1732557
1732557
-2108180664
"a"
"bee"
"포옹"
"kamala lifefully"
"đậu hũ"
Using Negative hash codes
Suppose that ‘s hash code is -1.
65
0
1
2
3
Using Negative hash codes
Suppose that ‘s hash code is -1.
66
0
1
2
3
-1
Using Negative hash codes in Java
Suppose that ‘s hash code is -1.
67
0
1
2
3
public class ModTest {
public static void main(String[] args) {
System.out.println(-1 % 4);
System.out.println(Math.floorMod(-1, 4));
}
}
$ java ModTest
-1
3
Hash Tables in Java
Java hash tables:
68
포옹
a
0
1
2
3
đậu hũ
đậu hũ
hashCode()
-2108180664
Math.floorMod(x, 4)
0
data
hash code
hash function
reduce
index
kamala lifefully
bee
Two Important Warnings When Using HashMaps/HashSets
Warning #1: Never store objects that can change in a HashSet or HashMap!
Warning #2: Never override equals without also overriding hashCode.
We’ll come back to these warnings later.
69
Hash Table Performance and Summary
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
70
Hash Table Runtime with No Resizing
Suppose we have:
Average list is around N/M items
Even if items are spread out evenly, lists are of length Q = N/M.
71
0
1
2
3
4
N = 19 M = 5 N / M = 3.8
Resizing Hash Table Runtime
Suppose we have:
As long as M = Θ(N), then O(N/M) = O(1).
Assuming items are evenly distributed (as above), lists will be approximately N/M items long, resulting in Θ(N/M) runtimes.
72
0
1
2
3
4
N = 19 M = 5 N / M = 3.8
Regarding Even Distribution
Even distribution of item is critical for good hash table performance.
Will need to discuss how to ensure even distribution.
73
x
x
Hash Tables in Java
Hash tables:
74
đậu hũ
hashCode()
-2108180664
Math.floorMod(x, 4)
0
data
hash code
hash function
reduce
index
*: Indicates “on average”.
†: Assuming items are evenly spread.
| contains(x) | add(x) |
Bushy BSTs | Θ(log N) | Θ(log N) |
Separate Chaining Hash Table With No Resizing | Θ(N) | Θ(N) |
… With Resizing | Θ(1)† | Θ(1)*† |
Creating a Good Hash Code (extra)
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
75
What Makes a good .hashCode()?
Goal: We want hash tables that look like the table on the right.
76
Hashbrowns and Hash Codes
How do you make hashbrowns?
77
Can think of multiplying data by powers of some base as ensuring that all the data gets scrambled together into a seemingly random integer.
Example hashCode Function
The Java 8 hash code for strings. Two major differences from our hash codes:
78
@Override
public int hashCode() {
int h = cachedHashValue;
if (h == 0 && this.length() > 0) {
for (int i = 0; i < this.length(); i++) {
h = 31 * h + this.charAt(i);
}
cachedHashValue = h;
}
return h;
}
Example: Choosing a Base
Java’s hashCode() function for Strings:
Our asciiToInt function for Strings:
Which is better?
79
Example: Base 126
Major collision problem:
Any string that ends in the same last 32 characters has the same hash code.
80
Typical Base
A typical hash code base is a small prime.
A full treatment of good hash codes is well beyond the scope of our class.
81
Hashbrowns and Hash Codes
How do you make hashbrowns?
82
Using a prime base yields better “randomness” than using something like base 126.
Example: Hashing a Collection
Lists are a lot like strings: Collection of items each with its own hashCode:
To save time hashing: Look at only first few items.
83
@Override
public int hashCode() {
int hashCode = 1;
for (Object o : this) {
hashCode = hashCode * 31;
hashCode = hashCode + o.hashCode();
}
return hashCode;
}
elevate/smear the current hash code
add new item’s hash code
Example: Hashing a Recursive Data Structure
Computation of the hashCode of a recursive data structure involves recursive computation.
84
@Override
public int hashCode() {
if (this.value == null) {
return 0;
}
return this.value.hashCode() +
31 * this.left.hashCode() +
31 * 31 * this.right.hashCode();
}
Linear Probing (extra)
Lecture 26, CS61B, Fall 2025
Motivation, Set Implementations
Deriving Hash Tables
Hash Table Performance and Summary
Hash Tables in Java
Creating a Good Hash Code (extra)
Linear Probing (extra)
85
Open Addressing: An Alternate Disambiguation Strategy (Extra)
Instead of using linked lists, an alternate and more exotic strategy is “open addressing”.
If target location is already occupied, use a different location, e.g.
In 61B, we’ll use the “separate chaining” approach, where we have linked lists.
86
Citations
http://en.wikipedia.org/wiki/Pigeonhole_principle#mediaviewer/File:TooManyPigeons.jpg
https://cookingplanit.com/public/uploads/inventory/hashbrown_1366322674.jpg
87
FAQ
What is the distinction between hash set, hash map, and hash table?
A hash set is an implementation of the Set ADT using the “hash table” as its engine.
A hash map is an implementation of the Map ADT using the “hash table” as its engine.
A “hash table” is a way of storing information, where you have M buckets that store N items. Each item has a “hashCode” that tells you which of M buckets to put that item in.
88
Attendance
89