Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 57ef7b1

Browse files
doc update
1 parent 40440d6 commit 57ef7b1

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

‎README.md‎

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
# java8-map-functions
22

3+
_Reference_: https://www.nurkiewicz.com/2014/04/hashmap-performance-improvements-in.html
4+
_Reference_: https://dzone.com/articles/java-8-hashmaps-keys-and-the-comparable-interface
5+
_Reference_: https://yermilov.github.io/blog/2017/02/24/tiebreaker-regarding-java-hashmap-treenode-and-tiebreakorder/
6+
7+
# preface
8+
Basically when a bucket becomes too big (currently: `TREEIFY_THRESHOLD = 8`),
9+
`HashMap` dynamically replaces it with an ad-hoc implementation of tree
10+
map. This way rather than having pessimistic `O(n)` we get much better
11+
`O(logn)`. How does it work? Well, previously entries with conflicting
12+
keys were simply appended to linked list, which later had to be traversed.
13+
Now `HashMap` promotes list into binary tree, using hash code as a
14+
branching variable. If two hashes are different but ended up in the
15+
same bucket, one is considered bigger and goes to the right. If hashes
16+
are equal (as in our case), `HashMap` hopes that the keys are `Comparable`,
17+
so that it can establish some order. This is not a requirement of
18+
`HashMap` keys, but apparently a good practice. If keys are not
19+
comparable, don't expect any performance improvements in case of heavy
20+
hash collisions.
21+
22+
The tree implementation inside the `HashMap` is a `Red-Black` tree, which
23+
means it will always be balanced.
24+
25+
When the `HashMap` implementation tries to find the location of a new
26+
entry in the tree,
27+
first it checks whether the current and the new values are easily
28+
comparable (`Comparable` interface) or not. In the latter case, it has
29+
to fall back to a comparison method called `tieBreakOrder(Object a,
30+
Object b)`. This method tries to compare the two object based on class
31+
name first, and then using `System.identityHashCode`. However, when
32+
the key implements Comparable, the process is much simpler. The key
33+
itself defines how it compares to other keys, so the whole
34+
insertion/retrieval process speeds up, as there are no extra method
35+
calls needed for. It's worth mentioning that the same `tieBreakOrder`
36+
method is used when two Comparable keys turn out to be equal according
37+
to the compareTo method (the method returns 0).
38+
39+
# summary
40+
## comparing
341
* `public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey()`
442
* `public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue()`
543
* `public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp)`
644
* `public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp)`
7-
* `default V getOrDefault(Object key, V defaultValue)`
45+
46+
## processing
847
* `default void forEach(BiConsumer<? super K, ? super V> action)`
948
* `default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)`
49+
50+
# modifying
51+
* `default V getOrDefault(Object key, V defaultValue)`
1052
* `default V putIfAbsent(K key, V value)`
1153
* `default boolean remove(Object key, Object value)`
1254
* `default boolean replace(K key, V oldValue, V newValue)`

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /