-
-
Notifications
You must be signed in to change notification settings - Fork 638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-worked TreeMap comparators, considering null-keys #1695
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments
@@ -448,7 +448,7 @@ private TreeMap(RedBlackTree<Tuple2<K, V>> entries) { | |||
* @return A new Map containing the given entries | |||
*/ | |||
public static <K, V> TreeMap<K, V> of(Comparator<? super K> keyComparator, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { | |||
return of(keyComparator, k1, v1, k2, v2, k3, v3).put(k4, v4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous version called TreeMap.put, which was bad for these reasons:
- TreeMap.put was called, which creates RedBlackTree-wrappers
- of(...) recursively called O(n) times of() before starting to add values
The current version
- calls put on RedBlackTree, which does not create intermediate TreeMap objects
- turns the recursive call into an iteration, which is more efficient in this case
@@ -37,7 +37,7 @@ protected String className() { | |||
|
|||
@Override | |||
protected <T1 extends Comparable<? super T1>, T2> TreeMap<T1, T2> emptyMap() { | |||
return TreeMap.empty(nullsFirst()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using nullsFirst() was terribly wrong. It made unit tests artificially work which were not intended to work.
1, null, 2, null, 3, null); | ||
treeMap2.get(2); | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will remove this in a second...
for (Tuple2<? extends K, ? extends V> entry : entries) { | ||
tree = tree.insert((Tuple2<K, V>) entry); | ||
} | ||
return tree.isEmpty() ? (TreeMap<K, V>) empty() : new TreeMap<>(tree); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was wrong, because the comparator was not used in the empty case
Objects.requireNonNull(keyComparator, "keyComparator is null"); | ||
Objects.requireNonNull(entry, "entry is null"); | ||
return TreeMap.<K, V> empty(keyComparator).put(entry); | ||
public static <K, V> TreeMap<K, V> ofAll(Comparator<? super K> keyComparator, java.util.Map<? extends K, ? extends V> map) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method was missing
Current coverage is 97.04% (diff: 89.07%)@@ master #1695 diff @@
==========================================
Files 89 89
Lines 11247 11277 +30
Methods 0 0
Messages 0 0
Branches 1888 1888
==========================================
+ Hits 10917 10944 +27
- Misses 187 193 +6
+ Partials 143 140 -3
|
} | ||
|
||
@Override | ||
public <K2, V2> TreeMap<K2, V2> bimap(Comparator<? super K2> keyComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
} | ||
|
||
@Override | ||
public <K2, V2> TreeMap<K2, V2> bimap(Comparator<? super K2> keyComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
@@ -1225,34 +1183,201 @@ public String toString() { | |||
return mkString(stringPrefix() + "(", ", ", ")"); | |||
} | |||
|
|||
// -- private helpers | |||
|
|||
private static <K, K2, V, V2> TreeMap<K2, V2> bimap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
@@ -1225,34 +1183,201 @@ public String toString() { | |||
return mkString(stringPrefix() + "(", ", ", ")"); | |||
} | |||
|
|||
// -- private helpers | |||
|
|||
private static <K, K2, V, V2> TreeMap<K2, V2> bimap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return createTreeMap(entryComparator, map.entries, entry -> entry.map(keyMapper, valueMapper)); | ||
} | ||
|
||
private static <K, V, K2, V2> TreeMap<K2, V2> flatMap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return createTreeMap(entryComparator, map.entries, entry -> entry.map(keyMapper, valueMapper)); | ||
} | ||
|
||
private static <K, V, K2, V2> TreeMap<K2, V2> flatMap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> map(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> map(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return new TreeMap<>(tree); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> createTreeMap(EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
return new TreeMap<>(tree); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> createTreeMap(EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it must not
|
||
private static final long serialVersionUID = 1L; | ||
|
||
final Comparator<K> keyComparator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private: ok
accessor methods: oh my god - no! (no getters and setters please. we have keyComparator())
} | ||
|
||
@Override | ||
public <K2, V2> TreeMap<K2, V2> bimap(Comparator<? super K2> keyComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'K2' must match pattern '^[A-Z]$'.
} | ||
|
||
@Override | ||
public <K2, V2> TreeMap<K2, V2> bimap(Comparator<? super K2> keyComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'V2' must match pattern '^[A-Z]$'.
@@ -1225,34 +1183,201 @@ public String toString() { | |||
return mkString(stringPrefix() + "(", ", ", ")"); | |||
} | |||
|
|||
// -- private helpers | |||
|
|||
private static <K, K2, V, V2> TreeMap<K2, V2> bimap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'K2' must match pattern '^[A-Z]$'.
@@ -1225,34 +1183,201 @@ public String toString() { | |||
return mkString(stringPrefix() + "(", ", ", ")"); | |||
} | |||
|
|||
// -- private helpers | |||
|
|||
private static <K, K2, V, V2> TreeMap<K2, V2> bimap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'V2' must match pattern '^[A-Z]$'.
return createTreeMap(entryComparator, map.entries, entry -> entry.map(keyMapper, valueMapper)); | ||
} | ||
|
||
private static <K, V, K2, V2> TreeMap<K2, V2> flatMap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'K2' must match pattern '^[A-Z]$'.
return createTreeMap(entryComparator, map.entries, entry -> entry.map(keyMapper, valueMapper)); | ||
} | ||
|
||
private static <K, V, K2, V2> TreeMap<K2, V2> flatMap(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'V2' must match pattern '^[A-Z]$'.
return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> map(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'K2' must match pattern '^[A-Z]$'.
return createTreeMap(entryComparator, map.entries.iterator().flatMap(entry -> mapper.apply(entry._1, entry._2))); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> map(TreeMap<K, V> map, EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'V2' must match pattern '^[A-Z]$'.
return new TreeMap<>(tree); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> createTreeMap(EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'K2' must match pattern '^[A-Z]$'.
return new TreeMap<>(tree); | ||
} | ||
|
||
private static <K, K2, V, V2> TreeMap<K2, V2> createTreeMap(EntryComparator<K2, V2> entryComparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Checkstyle] ERROR: Name 'V2' must match pattern '^[A-Z]$'.
This was the last fix for 2.0.5 - now starting to cherry-pick. |
Update: This behavioral change was reverted in #1696
Fixes #1549