Skip to content

Commit

Permalink
Containers in Depth: Exercise 26
Browse files Browse the repository at this point in the history
  • Loading branch information
kean0212 committed May 24, 2017
1 parent c007c94 commit d56136c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
55 changes: 55 additions & 0 deletions ContainersInDepth/CountedString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public class CountedString {
private static List<String> created = new ArrayList<String>();
private String string;
private int id = 0;
private char aChar;

public CountedString(String string, char aChar) {
this.string = string;
this.aChar = aChar;
created.add(string + aChar);
for (String createdString : created) {
if (createdString.equals(string + aChar)) {
id++;
}
}
}

public String toString() {
return "String: " + string + " id: " + id + " char: " + aChar + " hashCode(): " + hashCode();
}

public int hashCode() {
int result = 17;
result = 37 * result + string.hashCode();
result = 37 * result + id;
result = 37 * result + (int) aChar;
return result;
}

public boolean equals(Object object) {
return object instanceof CountedString &&
string.equals(((CountedString) object).string) &&
id == ((CountedString) object).id &&
aChar == ((CountedString) object).aChar;
}

public static void main(String[] args) {
Map<CountedString, Integer> map = new HashMap<CountedString, Integer>();
CountedString[] countedStrings = new CountedString[5];
for (int i = 0; i < countedStrings.length; ++i) {
countedStrings[i] = new CountedString("hi", (char) ('a' + i));
map.put(countedStrings[i], i);
}
Util.println(map);
for (CountedString countedString : countedStrings) {
Util.println("Looking up " + countedString);
Util.println(map.get(countedString));
}
}
}
24 changes: 22 additions & 2 deletions ContainersInDepth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,26 @@ This means that we should pay attention to whether override `entrySet()` or not
Therefore, all of the methods have been implemented.
Many methods depend on `entrySet()` which makes `entrySet()` important.

I spent most of today on work even after work time...

### Overriding hashCode()
1. The most important factor in creating a `hashCode()` is that, regardless of when `hashCode()` is called,
it produces the same value for a particular object every time.
Otherwise, it will be impossible to access the stored ones.

2. Do **NOT** use unique object information, such as the address.
Otherwise, it will be impossible again.
For example,
```java
map.put(instance); // where instance.hashCode() is based on `this`
Instance instance2 = instance;
map.get(instance2); // this will return `null`
```

3. Another factor needs to consider while overriding `hashCode()` is to ensure an even distribution,
so that less collisions happen.
According to ***Effective Java***, use `result = 37* result + c` where `c` is the `hashCode` of each field of the class.

**Note**:
1. The access modifiers are controlling class access, not instance access.
That's why in 'equals()', private fields can be accessed.
[CountedString.java](https://github.com/kean0212/Thinking-In-Java-Notes/blob/master/ContainersInDepth/CountedString.java#37).

0 comments on commit d56136c

Please sign in to comment.