First, let’s take an outline of how hashtable works. Each entry has a key that has a hash code and a price. Keys have to be comparable in some trend. Many alternative keys can have the identical hash code, although in follow we wish this to are typically true solely of keys which can be additionally thought of equal.
Internally a hashtable shops a set of buckets, usually in a easy array. Every bucket comprises 0..N entries, every of which has a key and a price. To seek out what bucket an entry goes into we generate a numeric hashcode for the important thing, and decide what bucket index from hashcode mod the variety of buckets.
Let’s create an Entry
class. We want a key, which might’t change, a price, which might change, and a pointer to subsequent so we are able to make our array that has 0..N entries in every spot. One thing like this could do it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package deal org.techzoo.util;
public class Entry<Ok, V> {
non-public Entry<Ok, V> subsequent;
non-public remaining Ok key;
non-public V worth;
public Entry(Ok key, V worth) {
this.key = key;
this.setValue(worth);
}
public Ok getKey() {
return key;
}
public void setValue(V worth) {
this.worth = worth;
}
public V getValue() {
return worth;
}
public void setNext(Entry<Ok, V> subsequent) {
this.subsequent = subsequent;
}
public Entry<Ok, V> getNext() {
return subsequent;
}
}
|
Now let’s create a HashMap
class. The primary operation we’ll implement is get. We’ll have to establish what bucket to make use of, then cycle by way of the 0..N entries for that bucket to see if any of them have the precise key we’re excited by.
If there’s nothing in any respect within the bucket we are able to simply create a brand new entry and shove it in. If there’s already 1..N issues there we have to search by way of all of them. If we discover one with the very same key we’ll replace it, in any other case we’ll simply shove a brand new entry on the top.
Placing all of it collectively our remaining hashmap seems to be like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package deal org.techzoo.util;
public class MyHashMap<Ok, V> {
non-public int DEFAULT_BUCKET_COUNT = 10;
non-public Entry<Ok, V>[] buckets;
public MyHashMap() {
buckets = new Entry[DEFAULT_BUCKET_COUNT];
}
public MyHashMap(int capability) {
buckets = new Entry[capability];
}
public V get(Ok key) {
throwIfKeyNull(key);
Entry<Ok, V> entry = buckets[bucketIndexForKey(key)];
whereas (entry != null && !key.equals(entry.getKey()))
entry = entry.getNext();
return entry != null ? entry.getValue() : null;
}
public void put(Ok key, V worth) {
throwIfKeyNull(key);
int bucketIndex = bucketIndexForKey(key);
Entry<Ok, V> entry = buckets[bucketIndex];
if (null != entry) {
boolean carried out = false;
whereas (!carried out) {
if (key.equals(entry.getKey())) {
entry.setValue(worth);
carried out = true;
} else if (entry.getNext() == null) {
entry.setNext(new Entry<Ok, V>(key, worth));
carried out = true;
}
entry = entry.getNext();
}
} else {
// nothing there in any respect; simply shove the brand new entry in
buckets[bucketIndex] = new Entry<Ok, V>(key, worth);
}
}
public int bucketIndexForKey(Ok key) {
int bucketIndex = key.hashCode() % buckets.size;
return bucketIndex;
}
non-public void throwIfKeyNull(Ok key) {
if (key == null) {
throw new IllegalArgumentException(“key is probably not null”);
}
}
}
|
Following is a JUnit check case to confirm the functianality.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package deal org.techzoo.util;
import static org.junit.Assert.*;
import static java.lang.String.format;
import org.junit.Take a look at;
public class MyHashMapTest {
@Take a look at
public void readWriteSimpleValue() {
MyHashMap<String, Duck> map = new MyHashMap<String, Duck>();
map.put(“duck”, new Duck(“duck”,2));
map.put(“goose”, new Duck(“goose”,4));
assertEquals(2, map.get(“duck”).getWeight());
assertEquals(4, map.get(“goose”).getWeight());
}
@Take a look at
public void getSomethingThatIsntThere() {
MyHashMap<Integer, String> map = new MyHashMap<Integer, String>();
assertEquals(null, map.get(42));
}
@Take a look at
public void overWriteValue() {
MyHashMap<Integer, String> map = new MyHashMap<Integer, String>();
map.put(42, “meh”);
assertEquals(“meh”, map.get(42));
map.put(42, “we now have the expertise to rebuild him”);
assertEquals(“we now have the expertise to rebuild him”, map.get(42));
}
/**
* A easy Util class
**/
class Duck {
non-public String title;
non-public int weight;
public Duck(String title, int weight){
this.title = title;
this.weight = weight;
}
public String getName(){return title;}
public int getWeight(){return weight;}
@Override
public String toString(){
return format(“title:tpercentstweight:tpercentd”);
}
}//class
}
|
Supply techzoo.org