8 Haziran 2020 Pazartesi

Comparator Arayüzü

Giriş
İki nesneyi belirlediğimiz kritere göre kıyaslamak için kullanılır. Java 8 ile Comparator arayüzü yeni metodlara sahip oldu.

Comparator max(), sort() gibi işlemler için kullanılır.

Örnek - Stream
Max işlemi için kullanırız. Şöyle yaparız.
stream.max(Comparator.comparingInt(...).get()
Örnek - Stream
Sort işlemi için kullanırız. Şöyle yaparız.
stream.sort(Comparator.comparing(...));
Örnek - Collections
Şöyle yaparız
List<String> list = ...
Collections.sort(list, Comparator<.comparing(...));
Örnek - List
List sort işlemi için şöyle yaparız.
list.sort(Comparator.comparingInt(...)));
compare metodu
İmzası şöyle.
@FunctionalInterface
public interface Comparator<T> {
  int compare(T o1, T o2);
  ...
}
Açıklaması şöyle.
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
Kalıtan sınıfta imza şöyle olur.
public int compare (Foo o1, Foo o2);
Bu metodu gerçekleştirmek yerine comparingX metodlarını terchi etmek daha iyi olabilir. Şöyle yaparız.
weightList.sort(Comparator.comparingInt(Weight::getWeight));
Örnek
Şöyle yaparız. o1 diğer nesneden büyükse 1, diğer nesneye eşitse 0, küçükse -1 dönerim.
class FooComparator implements Comparator<Foo> {
  @Override
  public int compare (BankAccount o1, BankAccount o2) {
    return ...;
  }
}
Örnek
Yardımcı sınıfların metodlarını kullanmak iyi olabilir. Şöyle yaparız.
public int compare(Weight o1, Weight o2) {
  return Integer.compare(o1.getWeight(), o2.getWeight());
}
Örnek
Eğer sıralamada null daha küçük kabul etmek istersek şöyle yaparız.
public int compare (Foo o1, Foo o2) {
  if (o1 == o2) {
    return 0;
  }
  if (o1 == null) {
    return -1;
  }
  if (o2 == null) {
    return 1;
  }
  ...
  return ...;
}
comparing metodu - keyExtractor
Comparator.comparing metodu yazısına taşıdım.

comparing metodu - keyExtractor + keyComparator
Comparator.comparing metodu yazısına taşıdım.

comparingDouble metodu
Static factory metodudur. İki tane double değeri karşılaştıran Comparator nesnesi döner. Örnek ver.

comparingInt metodu - static
Static factory metodudur. İki tane int değeri karşılaştıran Comparator nesnesi döner. min (), max (), sort (), gibi işlemlerde kullanılabilir.
Eskiden şöyle yazardık.
List<String> al = Arrays.asList("45", "186", "185", "55", "51", "51", //
        "22", "78", "64", "26", "49", "21");
Collections.sort(al, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
    }
});
Örnek - Max
Şimdi şöyle yazıyoruz.
someStrings.stream().max(Comparator.comparingInt(String::length)).get()
Örnek - Sort
Şimdi şöyle yazıyoruz.
Collection.sort(al, Comparator.comparingInt(Integer::parseInt));
İki alan göre çalışan comparator şöyledir.
Collection.sort(personList, Comparator
    .comparingInt(Person::getAge)
    .thenComparing(Person::getSurname));
Örnek
Listede olmayan nesneleri en başa alan bir sort için şöyle yaparız
List<String> currencies = List.of("PLN","EUR","USD","GBP", "CHF");
Comparator<Object> objectComparator = Comparator.comparingInt(currencies::indexOf);
System.out.println(objectComparator.compare("JPY", "PLN")); //-1
System.out.println(objectComparator.compare("JPY", "TTT")); //0
System.out.println(objectComparator.compare("CHF", "GBP")); //1
comparingLong metodu

Static factory metodudur. İki tane long değeri karşılaştıran Comparator nesnesi döner. Şöyle yaparız.
List<Message> messagesByDeviceType = new ArrayList<Message>();      
messagesByDeviceType.sort(Comparator.comparingLong(Message::getTime))
Aslında sonuç şu kod ile aynıdır.
Long.compare(...,..)
naturalOrder metodu
Nesnelerin compareTo() metodunu kullanarak karşılaştırma yapar.
Örnek
Şöyle yaparız.
List<Double> items = Arrays.asList(9.0, 4.0, 16.0, -6.0, 5.0);
double max = items.stream().max(Comparator.naturalOrder()).get();
double min = items.stream().min(Comparator.naturalOrder()).get();
System.out.println(min + " " + max);
Çıktı olarak şunu alırız
-6.0 16.0
Örnek
Şöyle yaparız.
Comparator.comparing(Foo::getName,Comparator.nullsLast(Comparator.naturalOrder()))
nullsFirst metodu
İmzası şöyle.
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
Şöyle yaparız.
Comparator<String> cmp = Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER);
TreeMap<String, String> map = new TreeMap<>(cmp);
nullsLast metodu
İmzası şöyle.
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator)
reversed metodu
Normalde küçükten büyüğe sıralarken, büyükten küçüğe sıralama yapabilmeyi sağlar.
Örnek
Şöyle yaparız.
employeeList.sort(Comparator.comparing(Employee::getExperience).reversed());
Çıktı olarak şunu alırız
5.6 5.5 5.0 4.5 3.3
Örnek
Şöyle yaparız.
Comparator<Instant> cannotDoThis = (Instant::compareTo).reversed();
Örnek
Şöyle yaparız.
public static <T> Comparator<T> reverse(Comparator<T> comparator) {
  return comparator.reversed();
}
thenComparing metodu
İlk alan değerleri eşit ise ikinci alana göre sıralama yapmak için kullanılır.
Örnek
Şöyle yaparız.
Comparator.comparing(Drink::getName).
  thenComparing(Drink::getColour);
Örnek
Eğer Comparator nesnesini tekrar kullanmak istersek şöyle yaparız
Comparator<Entry<String, Integer>> cmp = Comparator.comparing(Entry::getValue);

bookshelf.entrySet()
         .stream()
         .sorted(cmp.thenComparing(Entry::getKey))
thenComparingDouble metodu
Örnek ver

thenComparingInt metodu
Örnek ver

thenComparingLong metodu
Örnek ver

Hiç yorum yok:

Yorum Gönder