Задача:
У вас есть список people
объектов класса Person
с полями name
и age
. Ваша задача - сначала отсортировать этот список по name
, а затем по age
.
Java 7:
Collections.sort(people, new Comparator<Person>() {
public int compare(Person a, Person b) {
return a.getName().compare(b.getName());
}
});
Collections.sort(people, new Comparator<Person>() {
public int compare(Person a, Person b) {
return Integer.valueOf(a.getAge()).compare(b.getAge());
}
});
Scala:
val sortedPeople = people.sortBy(p => (p.name, p.age))
Обновление
С тех пор, как я написал этот ответ, был достигнут некоторый прогресс. Лямбды (и ссылки на методы) наконец-то приземлились на Java, и они штурмом захватывают мир Java.
Вот как будет выглядеть приведенный выше код с Java 8 (предоставлено @fredoverflow):
people.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Хотя этот код почти такой же короткий, он работает не так элегантно, как Scala.
В решении Scala метод Seq[A]#sortBy
принимает функцию A => B
, где B
требуется, чтобы имел и Ordering
. Ordering
это тип-класс. Подумайте лучше об обоих мирах: как и Comparable
, это неявно для рассматриваемого типа, но, как и Comparator
, оно расширяемое и может быть добавлено ретроспективно к типам, у которых его нет. Поскольку в Java отсутствуют классы типов, он должен дублировать каждый такой метод, один раз для Comparable
, затем для Comparator
. Например, см. comparing
и thenComparing
здесь .
Классы типов позволяют писать правила, такие как «Если A имеет порядок, а B имеет порядок, то их кортеж (A, B) также имеет порядок». В коде это:
implicit def pairOrdering[A : Ordering, B : Ordering]: Ordering[(A, B)] = // impl
Вот как sortBy
в нашем коде может сравниваться по имени, а затем по возрасту. Эта семантика будет закодирована с указанным выше «правилом». Программист Scala интуитивно ожидает, что это будет работать именно так. Никаких специальных методов, таких как comparing
, не нужно было добавлять к Ordering
.
Лямбды и ссылки на методы - лишь вершина айсберга, который является функциональным программированием. :)