5 Mayıs 2016 Perşembe

Java 8 Functional Kullanımı

Giriş
Java 8 ile eklenen java.util.stream sınıfları ile functional programming yapılabilir. Bu sınıflar .Net'teki Linq sınıflarını andırıyorlar.

Functional Paketi
Java 8 Stream sınıflarını kullanabilmek için java.util.function paketi altındaki yapıları anlamak gerekir. Sebebini anlamadığım bir şekilde Java 8 her arity için bir isim kullanıyor.

Bu yapılardan önemli olanları şunlar.

Consumer : 1 parametre alır, void döner
Supplier : void alır , 1 sonuç döner
Predicate : 1 parametre alır, bool döner
Function  : 1 parametre alır ,1 sonuç döner


Şimdi bu kavramlara bakalım.

1. Consumer
Şu sınıflar var
BiConsumer

2. Supplier
Java 8 Supplier yazısına taşıdım.

3. Predicate
Java 8 Predicate yazısına taşıdım

4. Function
Şu sınıflar var

Annotationlar
@FunctionalInterface Anotasyonu yazısına taşıdım.

Ayrıca bir interface artık default olarak işaretli metodlar da sunabiliyor. Yani şöyle yapabiliyoruz.
public interface Drive {
  int getNumWheels();

  default int driveMiles(){
    return 10;
  }

  static int getColorID(){
    eturn 0;
  }
}
Eksikler
1. void alıp, void dönen Procedure gibi bir isimlendirmeyi unutmuşlar:)

2. Predicate + Function birlikte kullanımı - Yani Predicated Türevler
Function içinde bir Predicate olsun isteyelim. Eğer true ise bir sonuç, false ise başka bir sonuç dönelim. Yani şunu istiyoruz. Ama tabii Function içine Predicate vermek mümkün değil.
Predicate<Customer> IS_LEGACY_CUSTOMER = c -> c.getJoinedDate().isBefore(LocalDate.now()
  .minusYears(5));

Function<Customer, Integer> BONUS_POINTS_CALC = c -> {
  if(IS_LEGACY_CUSTOMER.test(c)) {
    return c.getDollarsSpent() * 4;
  } else {
    return c.getDollarsSpent() * 2;
  }
};
Örnek
Şöyle yaparız
public interface PredicatedFunction<T, R> extends Function<T, R> {

  static <T, R> Function<T, R> of(Function<? super T, ? extends R> f1, 
                                  Function<? super T, ? extends R> f2,
    Predicate<? super T> p) {
      return (T t) -> {
        if (p.test(t)) {
          return f1.apply(t);
        }
        return f2.apply(t);
      };
  }
}

Function<Customer, Integer> BONUS_POINTS_CALC = PredicatedFunction.of(
  c -> c.getDollarsSpent() * 4, // if true
  c -> c.getDollarsSpent() * 2, // if false
  c -> c.getJoinedDate().isBefore(LocalDate.now().minusYears(5));
Şöyle yaparız
public interface PredicatedUnaryOperator<T> extends UnaryOperator<T> {

  static <T> UnaryOperator<T> of(UnaryOperator<T> f, Predicate<? super T> p) {
    UnaryOperator<T> identity = UnaryOperator.identity();
    return (T t) -> {
      if (p.test(t)) {
        return f.apply(t);
      }
      return identity.apply(t);
    };
  }
}
Şöyle yaparız
public interface PredicatedConsumer<T> extends Consumer<T> {
  static <T> Consumer<T> of(Consumer<? super T> c, Predicate<? super T> p) {
    return (T t) -> {
      if (p.test(t)) {
        c.accept(t);
      }
    };
  }
}

Consumer<Message> NEW_MESSAGE_PROCESSOR = PredicatedConsumer.of(
  m -> processMessage(m) ,
  m -> m.getOriginationTime().isBefore(LocalDateTime.now().minusMinutes(5)));






Hiç yorum yok:

Yorum Gönder