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