16 Ocak 2019 Çarşamba

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
Max işlemi için kullanırız. Şöyle yaparız.
stream.max(Comparator.comparingInt(...).get()
Örnek
Sort işlemi için kullanırız. Şöyle yaparız.
stream.sort(Comparator.comparing(...));
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
Static factory metodudur. Normalde küçükten büyüğe sıralama sağlar.
Örnek
Büyükten küçüğe sıralama için şöyle yaparız.
employeeList.sort(Comparator.comparing(Employee::getExperience).reversed());
Örnek
Her iki alana göre sıralı olup olmadığını bulmak için şöyle yaparız.
<T, R extends Comparable<? super R>> boolean isSorted(List<T> list, Function<T, R> f) {
  Comparator<T> comp = Comparator.comparing(f);
  for (int i = 0; i < list.size() - 1; ++i) {
    T left = list.get(i);
    T right = list.get(i + 1);
    if (comp.compare(left, right) >= 0) {
      return false;
    }
  }

  return true;
}
Kullanmak için şöyle yaparız.
System.out.println(
          isSorted(myList, MyObj::getPercentage) && 
          isSorted(myList, MyObj::getDate));
comparing metodu - keyExtractor + keyComparator
Static factory metodudur. key'leri ürettikten sonra, keyComparator metodunu çağırır.
Örnek
Ters dizmek için şöyle yaparız.
Comparator.comparing(Test::getNumber, Comparator.reverseOrder());
Örnek
null değerlerin önce gelmesini istersek şöyle yaparız.
Comparator.comparing(Person::getName,
 Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER))
Çıktı olarak şunu alırız.
null
Alice
Bob
Bob
Carol
Carol
David
Eric
Örnek
poNumber alanına göre küçükten büyüğe sıralamak için şöyle yaparız. Alan null ise en öne gelir. Eğer iki alanın değerş aynı ise created alanına göre sıralama yapar.
import static java.util.Comparator.*; // for the sake of brevity

Set<Photo> orderedPhotos = new TreeSet<>(
    Comparator.comparing(Photo::getPoNumber, nullsFirst(naturalOrder()))
              .thenComparing(Photo::getCreated));
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));
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 büyüktür ve küçüktür karşılaştırmasını kullanır.
Ö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. Şöyle yaparız.
Comparator.comparing(Drink::getName).
  thenComparing(Drink::getColour);
thenComparingDouble metodu
Örnek ver

thenComparingInt metodu
Örnek ver

thenComparingLong metodu
Örnek ver

Hiç yorum yok:

Yorum Gönder