Tarefa:
Você tem uma lista people
de objetos de classe Person
que contém os campos name
e age
. Sua tarefa é classificar essa lista primeiro por name
e depois por 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))
Atualizar
Desde que escrevi esta resposta, houve algum progresso. Os lambdas (e as referências de método) finalmente chegaram ao Java e estão conquistando o mundo Java.
Esta é a aparência do código acima com Java 8 (contribuição de @fredoverflow):
people.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Embora esse código seja quase tão curto, ele não funciona tão elegantemente quanto o do Scala.
Na solução Scala, o Seq[A]#sortBy
método aceita uma função A => B
onde B
é necessário ter um Ordering
. Ordering
é uma classe-tipo. Pense melhor nos dois mundos: tipo Comparable
, é implícito para o tipo em questão, mas tipo Comparator
, é extensível e pode ser adicionado retrospectivamente a tipos que não o tinham. Como Java não possui classes de tipo, ele deve duplicar cada um desses métodos, uma vez para Comparable
, depois para Comparator
. Por exemplo, veja comparing
e thenComparing
aqui .
As classes de tipo permitem escrever regras como "Se A tem ordenação e B tem ordenação, então sua tupla (A, B) também tem ordenação". Em código, isto é:
implicit def pairOrdering[A : Ordering, B : Ordering]: Ordering[(A, B)] = // impl
É assim que o sortBy
em nosso código pode ser comparado por nome e depois por idade. Essas semânticas serão codificadas com a "regra" acima. Um programador de Scala intuitivamente espera que isso funcione dessa maneira. Nenhum método de propósito especial como comparing
teve que ser adicionado Ordering
.
Lambdas e referências de método são apenas a ponta de um iceberg que é a programação funcional. :)