Задача:
У вас есть список 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());
}
});
Скала:
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
.
Лямбда-выражения и ссылки на методы - это лишь верхушка айсберга функционального программирования. :)