Implementacje typu TreeSet i TreeMap umożliwiają porządkowanie danych, gdyż są one układane w kolekcji według operacji porównywania. Domyślnie w TreeSet i TreeMap dane są sortowane według porządku naturalnego (w kolejności: A B C D…). Jeżeli chcemy zastosować inny rodzaj sortowania powinniśmy użyć własnego komparatora podczas tworzenia instancji obiektu TreeSet lub TreeMap.

Warto zauważyć ze w Javie 8 rozbudowano klasę komparatorów i mamy kilka przydatnych metod:

  • reversed – zwraca komparator przeciwny do stworzonego w klasie (do bierzącego)
  • naturalOrder – zwraca komparator zajmujący się porównywaniem w „porządku naturalnym”
  • reverseOrder – zwraca komparator zajmujący się porównywaniem w „odwrotnym porządku naturalnym”
  • thenComparing – zawraca komparator umożliwiający zastosowanie podwójnego porównania. Działa w ten sposób, że jeżeli pierwsze porównanie poda, że obiekty są ze sobą równe to następuje porównanie przy pomocy drugiego komparatora
  • nullsFirst – zwraca komparator, który null’e traktuje jako mniejsze od wartości
  • nullsLast – zwraca komparator, który null’e traktuje jako większe od wartości
  • comparing – zwraca komparator który wykorzystuje klucze do porównywania danych.

Są również specjalizowane funkcje do porównywania prostych typów: comparingInt, comparingLong, comparingDouble

Tworzenie i używanie komparatorów:

//
// Tworzenie własnego komparatora w stary sposób
//
class RevComp implements Comparator<String>{
 
   @Override
   public int compare(String o1, String o2){
      return o2.compareToIgnoreCase(o1);
   }
}
 
//
// Tworzenie komparatora przy pomocy lambda
//
Comparator<String> comp2 = (o1, o2) -> {
   return o2.compareToIgnoreCase(o1);
};
 
//
// Tworzenie komparatora jako lambda podczas tworzenia instancji klasy
//
TreeSet<String> treeSet1 = new TreeSet<String>((o1, o2) -> o2.compareToIgnoreCase(o1));
treeSet1.add("Pierwszy");
treeSet1.add("Drugi");
treeSet1.add("Trzeci");
treeSet1.add("Czwarty");
 
TreeSet<String> treeSet2 = new TreeSet<>();
treeSet2.addAll(treeSet1);
 
TreeSet<String> treeSet3 = new TreeSet<>(new RevComp());
treeSet3.addAll(treeSet1);
 
TreeSet<String> treeSet4 = new TreeSet<>(comp2.reversed());
treeSet3.addAll(treeSet1);
 
//
// Wyświetlenie danych
//
System.out.println("Standartowe tworzenie komparatora: "+treeSet1.toString());
System.out.println("Komparator przy pomocy lambda: "+treeSet1.toString());
System.out.println("Lambda podczas tworzenia instancji: "+treeSet1.toString());
System.out.println("Odwrócony komparator: "+treeSet1.toString());