Skip to content

Commit 0cce7b9

Browse files
author
jsquared21
committed
Add Ex_27.05
1 parent 55d567e commit 0cce7b9

12 files changed

+477
-0
lines changed
1.58 KB
Binary file not shown.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*********************************************************************************
2+
* (Implement MyHashSet using MyHashMap) Implement MyHashSet using MyHashMap. *
3+
* Note that you can create entries with (key, key), rather than (key, value). *
4+
*********************************************************************************/
5+
public class Exercise_27_05 {
6+
public static void main(String[] args) {
7+
// Create a MyHashSet
8+
MySet<String> set = new MyHashSet<>();
9+
set.add("Smith");
10+
set.add("Anderson");
11+
set.add("Lewis");
12+
set.add("Cook");
13+
set.add("Smith");
14+
15+
System.out.println("Elements in set: " + set);
16+
System.out.println("Number of elements in set: " + set.size());
17+
System.out.println("Is Smith in set? " + set.contains("Smith"));
18+
19+
set.remove("Smith");
20+
System.out.println("Names in set in uppercase are ");
21+
for (String s: set)
22+
System.out.print(s.toUpperCase() + " ");
23+
24+
set.clear();
25+
System.out.println("\nElements in set: " + set);
26+
}
27+
}
4.6 KB
Binary file not shown.
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import java.util.LinkedList;
2+
3+
public class MyHashMap<K, V> implements MyMap<K, V> {
4+
// Define the default hash-table size. Must be a power of 2
5+
private static int DEFAULT_INITIAL_CAPACITY = 4;
6+
7+
// Define the maximum hash-table size 1 << 30 is same as 2^30
8+
private static int MAXIMUM_CAPACITY = 1 << 30;
9+
10+
// Current hash-table capacity. Capacity is a power of 2
11+
private int capacity;
12+
13+
// Define default load factor
14+
private static float DEFAULT_MAX_LOAD_FACTOR = 0.75f;
15+
16+
// Specify a load factor used in the hash table
17+
private float loadFactorThreshold;
18+
19+
// The number of entries in the map
20+
private int size = 0;
21+
22+
// Hash table is an array with each cell being a linked list
23+
LinkedList<MyMap.Entry<K, V>>[] table;
24+
25+
/** Construct a map with the default capacity and load factor */
26+
public MyHashMap() {
27+
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_LOAD_FACTOR);
28+
}
29+
30+
/** Construct a map with the specified initial capacity and
31+
* default load factor */
32+
public MyHashMap(int initialCapacity) {
33+
this(initialCapacity, DEFAULT_MAX_LOAD_FACTOR);
34+
}
35+
36+
/** Construct a map with the specified initial capacity
37+
* and load factor */
38+
public MyHashMap(int initialCapacity, float loadFactorThreshold) {
39+
if (initialCapacity > MAXIMUM_CAPACITY)
40+
this.capacity = MAXIMUM_CAPACITY;
41+
else
42+
this.capacity = trimToPowerOf2(initialCapacity);
43+
44+
this.loadFactorThreshold = loadFactorThreshold;
45+
table = new LinkedList[capacity];
46+
}
47+
48+
@Override /** Remove all of the entries from this map */
49+
public void clear() {
50+
size = 0;
51+
removeEntries();
52+
}
53+
54+
@Override /** Return true if the specified key is in the map */
55+
public boolean containsKey(K key) {
56+
if (get(key) != null)
57+
return true;
58+
else
59+
return false;
60+
}
61+
62+
@Override /** Return true if this map contains the value */
63+
public boolean containsValue(V value) {
64+
for (int i = 0; i < capacity; i++) {
65+
if (table[i] != null) {
66+
LinkedList<Entry<K, V>> bucket = table[i];
67+
for (Entry<K, V> entry : bucket)
68+
if (entry.getValue().equals(value))
69+
return true;
70+
}
71+
}
72+
73+
return false;
74+
}
75+
76+
@Override /** Return a set of entries in the map */
77+
public java.util.Set<MyMap.Entry<K, V>> entrySet() {
78+
java.util.Set<MyMap.Entry<K, V>> set =
79+
new java.util.HashSet<>();
80+
81+
for (int i = 0; i < capacity; i++) {
82+
if (table[i] != null) {
83+
LinkedList<Entry<K, V>> bucket = table[i];
84+
for (Entry<K, V> entry: bucket)
85+
set.add(entry);
86+
}
87+
}
88+
89+
return set;
90+
}
91+
92+
@Override /** Return the value that matches the specified key */
93+
public V get(K key) {
94+
int bucketIndex = hash(key.hashCode());
95+
if (table[bucketIndex] != null) {
96+
LinkedList<Entry<K, V>> bucket = table[bucketIndex];
97+
for (Entry<K, V> entry: bucket)
98+
if (entry.getKey().equals(key))
99+
return entry.getValue();
100+
}
101+
102+
return null;
103+
}
104+
105+
@Override /** Return true if this map contains no entries */
106+
public boolean isEmpty() {
107+
return size == 0;
108+
}
109+
110+
@Override /** Return a set consisting of the keys in this map */
111+
public java.util.Set<K> keySet() {
112+
java.util.Set<K> set = new java.util.HashSet<>();
113+
114+
for (int i = 0; i < capacity; i++) {
115+
if (table[i] != null) {
116+
LinkedList<Entry<K, V>> bucket = table[i];
117+
for (Entry<K, V> entry : bucket) {
118+
set.add(entry.getKey());
119+
}
120+
}
121+
}
122+
123+
return set;
124+
}
125+
126+
@Override /** Add and entry (key, value) into the map */
127+
public V put(K key, V value) {
128+
if (get(key) != null) { // The key is already in the map
129+
int bucketIndex = hash(key.hashCode());
130+
LinkedList<Entry<K, V>> bucket = table[bucketIndex];
131+
for (Entry<K, V> entry: bucket)
132+
if (entry.getKey().equals(key)) {
133+
V oldValue = entry.getValue();
134+
// Replace old value with new value
135+
entry.value = value;
136+
// Return the old value for the key
137+
return oldValue;
138+
}
139+
}
140+
141+
// Check load factor
142+
if (size >= capacity * loadFactorThreshold) {
143+
if (capacity == MAXIMUM_CAPACITY)
144+
throw new RuntimeException("Exceeding maximum capacity");
145+
146+
rehash();
147+
}
148+
149+
int bucketIndex = hash(key.hashCode());
150+
151+
// Create a linked list for the bucket if not already created
152+
if (table[bucketIndex] == null) {
153+
table[bucketIndex] = new LinkedList<Entry<K, V>>();
154+
}
155+
156+
// Add a new entry (key, value) to hashtable[index]
157+
table[bucketIndex].add(new MyMap.Entry<K, V>(key, value));
158+
159+
size++; // Increase size
160+
161+
return value;
162+
}
163+
164+
@Override /** Remove the entries for the specifie key */
165+
public void remove(K key) {
166+
int bucketIndex = hash(key.hashCode());
167+
168+
// Remove the first entry that matches the key from a bucket
169+
if (table[bucketIndex] != null) {
170+
LinkedList<Entry<K, V>> bucket = table[bucketIndex];
171+
for (Entry<K, V> entry: bucket)
172+
if (entry.getKey().equals(key)) {
173+
bucket.remove(entry);
174+
size--; // Decrease size
175+
break; // Remove just one entry that matches the key
176+
}
177+
}
178+
}
179+
180+
@Override /** Return the number of entries in this map */
181+
public int size() {
182+
return size;
183+
}
184+
185+
@Override /** Return a set consisting of the values in this map */
186+
public java.util.Set<V> values() {
187+
java.util.Set<V> set = new java.util.HashSet<>();
188+
189+
for (int i = 0; i < capacity; i++) {
190+
if (table[i] != null) {
191+
LinkedList<Entry<K, V>> bucket = table[i];
192+
for (Entry<K, V> entry : bucket) {
193+
set.add(entry.getValue());
194+
}
195+
}
196+
}
197+
198+
return set;
199+
}
200+
201+
/** Hash function */
202+
private int hash(int hashCode) {
203+
return supplementalHash(hashCode) & (capacity - 1);
204+
}
205+
206+
/** Ensure the hashing is evenly distributed */
207+
private int supplementalHash(int h) {
208+
h ^= (h >>> 20) ^ (h >>> 12);
209+
return h ^ (h >>> 7) ^ (h >>> 4);
210+
}
211+
212+
/** Return a power of 2 for initialCapacity */
213+
private int trimToPowerOf2(int initialCapacity) {
214+
int capacity = 1;
215+
while (capacity < initialCapacity) {
216+
capacity <<= 1; // Same as capacity *= 2. <= is more efficient
217+
}
218+
219+
return capacity;
220+
}
221+
222+
/** Remove all entries from each bucket */
223+
private void removeEntries() {
224+
for (int i = 0; i < capacity; i++) {
225+
if (table[i] != null) {
226+
table[i].clear();
227+
}
228+
}
229+
}
230+
231+
/** Rehash the map */
232+
private void rehash() {
233+
java.util.Set<MyMap.Entry<K, V>> set = entrySet(); // Get entries
234+
capacity <<= 1; // Same as capacity *= 2. <= is more efficient
235+
table = new LinkedList[capacity]; // Crate a new hash table
236+
size = 0;
237+
238+
for (Entry<K, V> entry : set) {
239+
put(entry.getKey(), entry.getValue()); // Store to new table
240+
}
241+
}
242+
243+
@Override /** Return a string representation for this map */
244+
public String toString() {
245+
StringBuilder builder = new StringBuilder("[");
246+
for (int i = 0; i < capacity; i++) {
247+
if (table[i] != null && table[i].size() > 0)
248+
for (Entry<K, V> entry : table[i]) {
249+
builder.append(entry);
250+
}
251+
}
252+
253+
builder.append("]");
254+
return builder.toString();
255+
}
256+
}
Binary file not shown.
2.52 KB
Binary file not shown.

0 commit comments

Comments
 (0)