16 Mart 2020 Pazartesi

Consumer Arayüzü

Giriş
Şu satırı dahil ederiz.
import java.util.function.Consumer;
Açıklaması şöyle
Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.
Consumer verilen nesne ile bir işlem yapar ve void döner. IntConsumer, DoubleConsumer gibi özelleşmiş halleri vardır.

constructor - lambda
lambda içinde return değeri olsa bile lambda statement olduğu müddetçe sorun çıkmaz. Açıklaması şöyle
If the body of a lambda is a statement expression (that is, an expression that would be allowed to stand alone as a statement), it is compatible with a void-producing function type; any result is simply discarded.
Örnek - Statement Yerine Expression
Şu kod derlenmez. Çünkü true bir expression'dır ve derleyici başına return kelimesi eklemek zorundadır. Dolayısıyla sağ taraf artık Consumer olamaz.
s -> true
Örnek - Statement
String kabul eden ve bir şey dönmeyen consumer için şöyle yaparız. Aslında String.equals() çağrısı bir sonuç dönse bile derleyici tarafından dikkate alınmaz.
Consumer<String> p = ""::equals;
Örnek - Statement
Şöyle yaparız.
p = s -> "".equals(s);
Bu kodlar şununla aynıdır.
new Consumer<String>() {
  @Override
  public void accept(final String s) {
    "".equals(s);
  }
}
Örnek - Return Type Olan Metod
Consumer return type olsa bile derlenir. Şöyle yaparız.
public static int someFunction(int a) {
  return a;
}

public static void main(String[] args) {    
  Consumer<Integer> c = SomeClass::someFunction; 
}
accept metodu
İmzası şöyle.
void accept(T t);
Consumer arayüzünden kalıtıp ayrı bir sınıf yazmak yerine lambda kullanmak çok daha kolay. Ancak yine de eski tarzda yapmak istersek şöyle yaparız.
class PrintConsumer implements Consumer<String> {

  @Override
  public void accept(String bar) {
   ...
  }
}
andThen metodu
Metodun içi şöyle.
/**
  * Returns a composed {@code Consumer} that performs, in sequence, this
  * operation followed by the {@code after} operation. If performing either
  * operation throws an exception, it is relayed to the caller of the
  * composed operation.  If performing this operation throws an exception,
  * the {@code after} operation will not be performed.
  *
  * @param after the operation to perform after this operation
  * @return a composed {@code Consumer} that performs in sequence this
  * operation followed by the {@code after} operation
  * @throws NullPointerException if {@code after} is null
  */
default Consumer<T> andThen(Consumer<? super T> after) {
  Objects.requireNonNull(after);
  return (T t) -> { accept(t); after.accept(t); };
}
Önce accept() çağrısı yapar, daha sonra andThen içine verilen kodu çalıştırır.
Örnek
Şöyle yaparız.
Consumer<Integer> cons = in -> ...;
cons.andThen(in ->...)
Diğer
Klasik Kullanım
Consumer kendisine verilen nesneyi işler.
Örnek
Şöyle yaparız forEach () ile kullanılıyor ve ekranda nesneyi gösteriyor.
public class Main {
  public static void main(String[] args) {
    Consumer<Boolean> myConsumer = b -> System.out.println("b = " + b);

    Stream.of("aa", "bb", "cc")
      .map(Main::myBooleanFunction)
      .forEach(myConsumer);

  }

  static boolean myBooleanFunction(String s) {
    return s.startsWith("b");
  }
}

Hiç yorum yok:

Yorum Gönder