Selecting a specific comparator method when sorting
Remi Forax
forax at univ-mlv.fr
Thu Dec 6 12:45:43 PST 2012
On 12/06/2012 08:30 PM, Christian Mallwitz wrote:
> Hi
>
> I have been experimenting with some lambda sorting examples. Examples:
>
> List<String> list = new ArrayList<>();
> list.add("496");
> list.add("6");
> list.add("8128");
> list.add("28");
> list.add("33550336");
>
> list
> .stream()
>
> .sorted(Comparators.comparing((IntFunction<String>)
> Integer::parseInt)) // (1)
> .sorted(Comparators.<String>comparing(Integer::parseInt)) // (2)
>
> .forEach(x -> { System.out.println(x); });
>
> I understand in case (1) syntactically speaking the
> (IntFunction<String>) part is just a type cast. What is the name and
> specification for the <String> bit in (2)? Could you point me to the
> relevant Java spec parts?
<String> is the type argument.
when you call Comparators.comparing, you let the compiler figure by
itself what is the type argument, it's you case 1, the argument of
comparing is IntFunction<String> so the compiler infers that the type
argument, the T of <T> Comparator<T> comparing(IntFunction<T> fun) is
String. In case 2 you specify the type argument.
Java spec:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2
(the third phase)
>
> Additionally I want to share my attempt at a Schwartz Transformation -
> I have two versions: one version (A) requiring an additional class and
> one version (B) emitting a warning due to a type cast (which should be
> safe). Which one would you prefer? Any other feedback?
>
> Call as in:
>
> schwartz(list.stream(), Integer::parseInt).forEach(x -> {
> System.out.println(x); });
>
> A)
>
> public static<T, R extends Comparable<? super R>> Stream<T>
> schwartz(Stream<T> stream, Function<T, R> f) {
>
> // class Pair - type of second element of pair must be Comparable
> final class Pair<F, S extends Comparable<? super S>> {
> public final F first;
> public final S second;
> public Pair(F first, S second){ this.first = first;
> this.second = second; }
> }
>
> return stream
> .map(t -> new Pair<>(t, f.apply(t)))
> .sorted((p1, p2) -> p1.second.compareTo(p2.second))
> .map(p -> p.first);
> }
>
> B)
>
> @SuppressWarnings("unchecked")
> public static<T, R extends Comparable<? super R>> Stream<T>
> schwartz(Stream<T> stream, Function<T, R> f) {
>
> return stream
> .map(t -> new Object[]{t, f.apply(t)})
> .sorted((o1, o2) -> ((Comparable) o1[1]).compareTo(o2[1]))
> .map(o -> ((T) o[0]));
> }
A is better IMO, note that you can also create a class Lazy<T> that is
Comparable and map from t to Lazy<T>, sort the Lazy<T> and go back to t.
>
> Cheers
> Christian
>
cheers,
Rémi
More information about the lambda-dev
mailing list