Skip to content

Commit 5d72fd3

Browse files
author
jsquared21
committed
Add Ex_27.4
1 parent fa2160f commit 5d72fd3

File tree

7 files changed

+369
-0
lines changed

7 files changed

+369
-0
lines changed
2.53 KB
Binary file not shown.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*********************************************************************************
2+
* (Modify MyHashMap with duplicate keys) Modify MyHashMap to allow duplicate *
3+
* keys for entries. You need to modify the implementation for the put(key,value) *
4+
* method. Also add a new method named getAll(key) that returns a set of values *
5+
* that match the key in the map. *
6+
*********************************************************************************/
7+
public class Exercise_27_04 {
8+
public static void main(String[] args) {
9+
// Create a map
10+
MyMap<String, Integer> map = new MyHashMap<>();
11+
map.put("Smith", 30);
12+
map.put("Anderson", 31);
13+
map.put("Lewis", 29);
14+
map.put("Cook", 29);
15+
map.put("Tom", 21);
16+
map.put("Mark", 21);
17+
map.put("Smith", 65);
18+
map.put("William", 21);
19+
20+
System.out.println("Entries in map: " + map);
21+
22+
System.out.println("The age of Lewis is " +
23+
map.get("Lewis"));
24+
25+
System.out.println("The age of William is " +
26+
map.get("William"));
27+
28+
System.out.println("The age of all Smith entries " +
29+
map.getAll("Smith"));
30+
31+
System.out.println("Is Smith in the map? " +
32+
map.containsKey("Smith"));
33+
34+
System.out.println("Is jay in the map? " +
35+
map.containsKey("Jay"));
36+
37+
System.out.println("Is age 33 in the map? " +
38+
map.containsValue(33));
39+
40+
System.out.println("Is age 31 in the map? " +
41+
map.containsValue(31));
42+
43+
System.out.print("Keys in map: ");
44+
for (String key : map.keySet()) {
45+
System.out.print(key + " ");
46+
}
47+
System.out.println();
48+
49+
System.out.print("Values in map: ");
50+
for (int value : map.values()) {
51+
System.out.print(value + " ");
52+
}
53+
System.out.println();
54+
55+
56+
map.remove("Smith");
57+
System.out.println("Entries in map " + map);
58+
59+
map.clear();
60+
System.out.println("Entries in map " + map);
61+
}
62+
}
4.42 KB
Binary file not shown.
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import java.util.ArrayList;
2+
3+
public class MyHashMap<K, V> implements MyMap<K, V> {
4+
// Define the default hash-table size. Must be 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.5f;
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 ArrayList
23+
private ArrayList<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 ArrayList<>();
46+
for (int i = 0; i < capacity; i++) {
47+
table.add(null);
48+
}
49+
}
50+
51+
@Override /** Remove all the entries from this map */
52+
public void clear() {
53+
size = 0;
54+
removeEntries();
55+
}
56+
57+
@Override /** Return true if the specified key is in the map */
58+
public boolean containsKey(K key) {
59+
if (get(key) != null)
60+
return true;
61+
else
62+
return false;
63+
}
64+
65+
@Override /** Return true if this map contains the value */
66+
public boolean containsValue(V value) {
67+
for (Entry<K, V> entry : table) {
68+
if (entry != null && entry.getValue() == 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<Entry<K, V>> entrySet() {
78+
java.util.Set<Entry<K, V>> set = new java.util.HashSet<>();
79+
80+
for (Entry<K, V> entry: table) {
81+
if (entry != null)
82+
set.add(entry);
83+
}
84+
85+
return set;
86+
}
87+
88+
@Override /** Return the value that matched the specified key */
89+
public V get(K key) {
90+
int index = hash(key.hashCode());
91+
int i = index - 1;
92+
93+
while (i != index && (table.get(index) == null ||
94+
table.get(index).getKey() != key)) {
95+
index++;
96+
index %= capacity;
97+
}
98+
99+
if (table.get(index).getKey() == key) {
100+
return table.get(index).getValue();
101+
}
102+
103+
return null;
104+
}
105+
106+
@Override /** Return a set of values that match the key in the map */
107+
public java.util.Set<V> getAll(K key) {
108+
java.util.Set<V> set = new java.util.HashSet<>();
109+
int index = hash(key.hashCode());
110+
int i = index - 1;
111+
112+
while (i != index) {
113+
if (table.get(index) != null && table.get(index).getKey() == key) {
114+
set.add(table.get(index).getValue());
115+
}
116+
index++;
117+
index %= capacity;
118+
}
119+
120+
return set;
121+
}
122+
123+
@Override /** Return true if this map contains no entries */
124+
public boolean isEmpty() {
125+
return size == 0;
126+
}
127+
128+
@Override /** Return a set consisting of the keys in this map */
129+
public java.util.Set<K> keySet() {
130+
java.util.Set<K> set = new java.util.HashSet<>();
131+
132+
for (Entry<K, V> entry: table) {
133+
if (entry != null)
134+
set.add(entry.getKey());
135+
}
136+
137+
return set;
138+
}
139+
140+
@Override /** Add an entry (key, value) into the map */
141+
public V put(K key, V value) {
142+
int index = hash(key.hashCode());
143+
144+
while (table.get(index) != null) {
145+
index++;
146+
index %= capacity;
147+
}
148+
149+
if (size >= capacity * loadFactorThreshold) {
150+
if (capacity == MAXIMUM_CAPACITY) {
151+
throw new RuntimeException("Exceeding maximum capacity");
152+
}
153+
rehash();
154+
}
155+
156+
// Add a new entry (key, value) to hash table
157+
table.set(index, new MyMap.Entry<K, V>(key, value));
158+
159+
size++; // Increase size
160+
161+
return value;
162+
}
163+
164+
@Override /** Remove the entry for the specified key */
165+
public void remove(K key) {
166+
int index = hash(key.hashCode());
167+
int i = index - 1;
168+
169+
while (i != index && (table.get(index) == null ||
170+
table.get(index).getKey() != key)) {
171+
index++;
172+
index %= capacity;
173+
}
174+
175+
if (table.get(index).getKey() == key) {
176+
table.remove(index);
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 all 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 (Entry<K, V> entry : table) {
190+
if (entry != null) {
191+
set.add(entry.getValue());
192+
}
193+
}
194+
195+
return set;
196+
}
197+
198+
/** Hash function */
199+
private int hash(int hashCode) {
200+
return supplementalHash(hashCode) & (capacity - 1);
201+
}
202+
203+
/** Ensure the hashing is evenly distributed */
204+
private int supplementalHash(int h) {
205+
h ^= (h >>> 20) ^ (h >>> 12);
206+
return h ^ (h >>> 7) ^ (h >>> 4);
207+
}
208+
209+
/** Return a power of 2 for initialCapacity */
210+
private int trimToPowerOf2(int initialcapacity) {
211+
int capacity = 1;
212+
while (capacity < initialcapacity) {
213+
capacity <<= 1;
214+
}
215+
216+
return capacity;
217+
218+
}
219+
220+
/** Remove all entries from map */
221+
private void removeEntries() {
222+
table.clear();
223+
}
224+
225+
/** Rehash the map */
226+
private void rehash() {
227+
capacity <<= 1; // Same as *= 2. <= is more efficient
228+
for (int i = size + 1; i < capacity; i++) {
229+
table.add(null);
230+
}
231+
}
232+
233+
@Override
234+
public String toString() {
235+
StringBuilder builder = new StringBuilder("[");
236+
237+
for (Entry<K, V> entry : table) {
238+
if (entry != null && size > 0) {
239+
builder.append(entry);
240+
}
241+
}
242+
243+
builder.append("]");
244+
return builder.toString();
245+
}
246+
}
970 Bytes
Binary file not shown.
909 Bytes
Binary file not shown.

Exercise_27/Exercise_27_04/MyMap.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
public interface MyMap<K, V> {
2+
/** Remove all of the entries from this map */
3+
public void clear();
4+
5+
/** Return true if the specified key is in the map */
6+
public boolean containsKey(K key);
7+
8+
/** Return true if this map contains the specified value */
9+
public boolean containsValue(V value);
10+
11+
/** Return a set of entries in the map */
12+
public java.util.Set<Entry<K, V>> entrySet();
13+
14+
/** Return the value that matches the specified key */
15+
public V get(K key);
16+
17+
/** Return a set of values that match the key in the map */
18+
public java.util.Set<V> getAll(K key);
19+
20+
/** Return true if this map doesn't contain any entries */
21+
public boolean isEmpty();
22+
23+
/** Return a set consisting of the keys in this map */
24+
public java.util.Set<K> keySet();
25+
26+
/** Add an entry (key, value) into the map */
27+
public V put(K key, V value);
28+
29+
/** Remove entry for the specified key */
30+
public void remove(K key);
31+
32+
/** Return the number of mappings in this map */
33+
public int size();
34+
35+
/** Return a set consisting of the values in this map */
36+
public java.util.Set<V> values();
37+
38+
/** Define an inner class for Entry */
39+
public class Entry<K, V> {
40+
K key;
41+
V value;
42+
43+
public Entry(K key, V value) {
44+
this.key = key;
45+
this.value = value;
46+
}
47+
48+
public K getKey() {
49+
return key;
50+
}
51+
52+
public V getValue() {
53+
return value;
54+
}
55+
56+
@Override
57+
public String toString() {
58+
return "[" + key + ", " + value + "]";
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)