Loose end: Comparators
Brian Goetz
brian.goetz at oracle.com
Mon Jun 10 13:39:11 PDT 2013
Henry has been working on the set of Comparator factories, combinators,
and defaults. His explorations covered a lot of ground, and involved
retreating in a few places where type inference didn't prove
cooperative. Here's where things are currently, and I'm pretty happy
with this as an outcome -- I think its about the right set, though we
can still niggle about naming and placement.
Comparators:
The (new) class Comparators goes away as a public class, now containing
only package-private implementations. The static methods from
Comparators have been sent to other, arguably more appropriate places
(as below -- some to Comparator, some to Map.Entry, some to BinaryOperator.)
Comparator -- static methods:
// Natural order
<T extends Comparable<? super T>> Comparator<T> naturalOrder()
// Natural order, reversed
<T extends Comparable<? super T>> Comparator<T> reverseOrder()
// Comparator from key extraction function (5 forms)
<T, U extends Comparable<? super U>> Comparator<T>
comparing(Function<? super T, ? extends U> keyExtractor)
<T, U> Comparator<T>
comparing(Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> cmp)
<T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor)
<T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor)
<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor)
// Null handling combinators
<T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
<T> Comparator<T> nullsLast(Comparator<? super T> comparator)
Comparator -- default methods:
// reverse the order of this comparator
Comparator<T> reversed()
// compose this comparator with another
Comparator<T> thenComparing(Comparator<? super T> other)
// compose this comparator with that implied by keyExtractor (x5)
Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor)
Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor)
Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor)
<U extends Comparable<? super U>> Comparator<T>
thenComparing(Function<? super T, ? extends U> keyExtractor)
<U> Comparator<T>
thenComparing(Function<? super T, ? extends U> keyExtractor,
Comparator<? super U> cmp)
BinaryOperator -- static methods:
// Was Comparators.lesserOf/greaterOf (useful as reducers)
<T> BinaryOperator<T> minBy(Comparator<? super T> comparator)
<T> BinaryOperator<T> maxBy(Comparator<? super T> comparator)
Map.Entry -- static methods:
// Was Comparators.naturalOrder{Keys,Values}
<K extends Comparable<? super K>, V>
Comparator<Map.Entry<K,V>> comparingByKey()
<K, V extends Comparable<? super V>>
Comparator<Map.Entry<K,V>> comparingByValue()
// Was Comparators.by{Key,Value}
<K, V> Comparator<Map.Entry<K, V>>
comparingByKey(Comparator<? super K> cmp)
<K, V> Comparator<Map.Entry<K, V>>
comparingByValue(Comparator<? super V> cmp)
Notable changes from recent Lambda versions:
- All attempts at adding "<S extends T>" flexibility have been rolled
back. This ran into conflicts with type inference that made it
impractical to overload the ref/int/long/double methods without mangling
the names (we're trying to restrict name mangling for cases where it
actually adds value, which is mostly when it describes the result type
of the operation, not the argument types.)
- Accordingly, comparingFromXxx have been renamed back to comparing.
- Static methods from Comparators have been sent to other, arguably
more appropriate, places.
More information about the lambda-libs-spec-experts
mailing list