Functional Interface

μžλ°”μ—μ„œ μ œκ³΅λ˜λŠ” ν‘œμ€€ API μ—μ„œ ν•œ 개의 μΆ”μƒλ©”μ„œλ“œλ₯Ό κ°€μ§€λŠ” μΈν„°νŽ˜μ΄μŠ€λ“€μ€ λͺ¨λ‘ λžŒλ‹€μ‹μ„ μ΄μš©ν•˜μ—¬ 읡λͺ… κ΅¬ν˜„ 객체둜 ν‘œν˜„μ΄ κ°€λŠ₯ν•˜λ‹€.
예λ₯Ό λ“€λ©΄ μŠ€λ ˆλ“œ μž‘μ—…μ„ μ •μ˜ν•˜λŠ” Runnable μΈν„°νŽ˜μ΄μŠ€λŠ” λ§€κ°œλ³€μˆ˜μ™€ 리턴값이 μ—†λŠ” run() λ©”μ„œλ“œλ§Œ μ‘°μž¬ν•˜κΈ° λ•Œλ¬Έμ— 닀름과 같이 λžŒλ‹€μ‹μ„ μ΄μš©ν•œ Runnable μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±μ‹œν‚¬μˆ˜ μžˆλ‹€.

public static void main(String[] args) {
  Runnable runnable = () -> {
    for (int i = 0; i < 10; ++i) {
      System.out.println(i);
    }
  };

  Thread thread = new Thread(runnable);
  thread.start();
}

@FunctionalInterface

λͺ¨λ“  μΈν„°νŽ˜μ΄μŠ€λ₯Ό λžŒλ‹€μ‹μ˜ νƒ€κ²Ÿ νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•  수 μ—†λ‹€.

λžŒλ‹€μ‹μ΄ ν•˜λ‚˜μ˜ λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•˜κΈ° λ•Œλ¬Έμ— λ‘κ°œ μ΄μƒμ˜ μΆ”μƒλ©”μ„œλ“œκ°€ μ„ μ–Έλœ μΈν„°νŽ˜μ΄μŠ€λŠ” λžŒλ‹€μ‹μ„ μ΄μš©ν•˜μ•  κ΅¬ν˜„ 객체λ₯Ό 생성할 수 μ—†λ‹€.

ν•˜λ‚˜μ˜ abstract method 만이 μ„ μ–Έ 된 μΈν„°νŽ˜μ΄μŠ€ 만이 lamda μ‹μ˜ Target Type 이 될 수 μžˆλ‹€.

FunctionalInterface λ₯Ό μž‘μ„±ν•  λ•Œ @FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ™μ—¬μ£Όλ©΄ λͺ…μ‹œμ μœΌλ‘œ FunctionalInterface μ΄λΌλŠ” 것을 μ•Œμˆ˜ 있으며 λ˜ν•œ λ‘κ°œμ΄μƒμ˜ 좔상 λ©”μ„œλ“œκ°€ μ„ μ–Έλ˜μ§€ μ•Šλ„λ‘ μ»΄νŒŒμΌλŸ¬κ°€ 체크 λ₯Ό ν•œλ‹€.

μ•„λž˜μ™€ 같이 λ‘κ°œ μ΄μƒμ˜ λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•œ FunctionalInterface 은 컴파일 μ—λŸ¬κ°€ λ‚œλ‹€.




Β 


@FunctionalInterface
public interface MyFunctionalInterface {
    public void method();
    public void otherMethod(); // Compile Error
}

μ•„λž˜μ™€ 같이 κ°„λ‹¨νžˆ λ§Œλ“€μ–΄ μ‚¬μš©κ°€λŠ₯ν•˜λ‹€.

λ§€κ°œλ³€μˆ˜κ°€ μžˆλŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

@FunctionalInterface
public interface MyFuncInterface {
  public int method(int x, int y);
}
public static void main(String[] args) {
  MyFuncInterface func = (x, y) => {
    return x + y;
  };

  int result = func(3, 5);

  System.out.println(result);
}
5

@FunctionalInterface
public interface Scoreable {
  int getScore();
}
@FunctionalInterface
public class ScoreCollection {
  private List<Scoreable> scores = new ArrayList<>();

  public void add (Scoreable scoreable) {
    scores.add(scoreable);
  }

  public int arithmeticMean() {
    int total = scores.stream().mapToInt(Scoreable::getScore).sum();
    return total / scores.size();
  }
}
class ScroeCollectionTest {
  @Test
  public void answerArithmeticMeanOfTwoNumbers() {
    ScoreCollection collection = new ScoreCollection();

    collection.add(() -> 5);
    collection.add(() -> 7);

    int actualResult = collection.arithmeticMean();

    assertEquals(actualResult, 6);
  }
}

참고자료

https://palpit.tistory.com/671

Java SE 8 λΆ€ν„°λŠ” λΉˆλ²ˆν•˜κ²Œ μ‚¬μš©λ˜λŠ” ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€ (Functional Interface) λŠ” java.util.function ν‘œμ€€ API νŒ¨ν‚€μ§€λ‘œ μ œκ³΅ν•©λ‹ˆλ‹€.
이 νŒ¨ν‚€μ§€μ—μ„œ μ œκ³΅ν•˜λŠ” ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ©μ μ€ λ©”μ„œλ“œ λ˜λŠ” μƒμ„±μžμ˜ λ§€κ°œνƒ€μž…μœΌλ‘œ μ‚¬μš©λ˜μ–΄ λžŒλ‹€μ‹μ„ λŒ€μž… ν•  수 μžˆλ„λ‘ ν•˜κΈ° μœ„ν•΄μ„œ 이닀.

java.util.function νŒ¨ν‚€μ§€μ˜ ν•¨μˆ˜μ  μΈν„°νŽ˜μ΄μŠ€λŠ” 크게 Consumer Supplier Function Operator Predicate 둜 κ΅¬λΆ„λœλ‹€.

Consumer

Consumer μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•μ€ 리턴값이 μ—†λŠ” accept() λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€.
accept() λ©”μ„œλ“œλŠ” λ§€κ°œκ°’μ„ μ†ŒλΉ„ν•˜λŠ” μ—­ν™œλ§Œ ν•œλ‹€.

Interface Name Abstract Method Description
Consumer<T> void accept(T t) 객체 T λ₯Ό 받아와 μ†ŒλΉ„
BiConsumer<T, U> void accept(T t, U u) 객체 T 와 U λ₯Ό λ°›μ•„ μ†ŒλΉ„
DoubleConsumer void accpet(double value) double 값을 λ°›μ•„ μ†ŒλΉ„
IntConsumer void accept(int value) int 값을 λ°›μ•„ μ†ŒλΉ„
LongConsumer void accept(long value) long 값을 λ°›μ•„ μ†ŒλΉ„
ObjDoubleConsumer<T> void accpet(T t, double value) 객체 T 와 double 값을 λ°›μ•„ μ†ŒλΉ„
ObjIntConsumer<T> void accept(T t, int value) 객체 T 와 int 값을 λ°›μ•„ μ†ŒλΉ„
ObjLongConsumer<T> void accept(T t, long value) 객체 T 와 long 값을 λ°›μ•„ μ†ŒλΉ„

Consumer<T> μΈν„°νŽ˜μ΄μŠ€λ₯Ό νƒ€κ²Ÿ νƒ€μž…μœΌλ‘œ ν•˜λŠ” λžŒλ‹€μ‹μ€ λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆλ‹€.

Consumer<String> consumer = t -> {
  /* t λ₯Ό μ†ŒλΉ„ν•˜λŠ” 싀행ꡬ문 */
};

μœ„ ꡬ문을 μ΄μš©ν•œ μ˜ˆμ œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

public static void main(String[] args) {
  Consumer<String> consumer = t -> System.out.println(t + "8");
  consumer.accept("Java SE ");

  BiConsumer<String, String> biConsumer = (t, u) -> System.out.println(t + u);
  biConsumer.accept("Java SE ", "8");

  DoubleConsumer doubleConsumer = d -> System.out.println("Java SE " + d);
  doubleConsumer.accept(8.0);

  ObjIntConsumer<String> objIntConsumer = (t, i) -> System.out.println(t + i);
  objIntConsumer.accept("Java SE ", 8);
}
Java SE 8
Java SE 8
Java SE 8.0
Java SE 8

forEach() λ₯Ό μ΄μš©ν•œ Consumer μΈν„°νŽ˜μ΄μŠ€μ˜ μ†ŒλΉ„ 방법이닀.

μ†ŒλΉ„μžμ˜ κ΄€μ μœΌλ‘œ forEach(Consumer<? super T> action) 둜 μ‚¬μš©ν•œλ‹€.

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEach {
  public static void main(String[] args) {
    List<Person> list = new ArrayList<>();
    list.add(new Persion(1, "KIM"));
    list.add(new Persion(2, "LEE"));
    list.add(new Persion(3, "PARK"));

    Consumer<Person> style = (Person p) -> System.out.println("id: " + p.getPid() + ", Name: " + p.getName());

    list.forEach(style);
  }
}
public class Person {
  private int pid;
  private String name;
  public Person() {}
  public Person(int pid, String name){
    this.pid = pid;
    this.name = name;
  }
  public int getPid() {
    return pid;
  }
  public void setPid(int pid) {
    this.pid = pid;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}
id:1, Name:KIM
id:2, Name:LEE
id:3, Name:PARK

λ˜ν•œ μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•œ μƒμ‚°μž κ΄€μ μ—μ„œ μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œμ΄λ‹€. (sort(Comparator<? super E> c))

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEach {
  public static void main(String[] args) {
    List<Person> list = new ArrayList<>();
    list.add(new Persion(1, "KIM"));
    list.add(new Persion(2, "LEE"));
    list.add(new Persion(3, "PARK"));

    Consumer<Person> style = (Person p) -> System.out.println("id: " + p.getPid() + ", Name: " + p.getName());

    list.sort(new PersonComparatorByName());

    list.forEach(style);
  }
}
import java.util.Comparator;
public class PersonComparatorByName implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}
// μ˜€λ¦„μ°¨μˆœ μ •λ ¬
id:1, Name:KIM
id:2, Name:LEE
id:3, Name:PARK

Supplier

Supplier μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•μ€ λ§€κ°œλ³€μˆ˜κ°€ μ—†κ³  리턴값이 μžˆλ‹€.
get 으둜 μ‹œμž‘ν•˜λŠ” μ΄λ¦„μ˜ λ©”μ„œλ“œλ₯Ό 가지고 있으며 이 λ©”μ„œλ“œλŠ” μ‹€ν–‰ν•œ ν›„ ν˜ΈμΆœν•œ 곳으둜 데이터λ₯Ό λ¦¬ν„΄ν•˜λŠ” μ—­ν™œμ„ ν•œλ‹€.

리턴 νƒ€μž…μ— λ”°λ₯Έ Supplier μΈν„°νŽ˜μ΄μŠ€λ“€μ΄ μžˆλ‹€.

Interface Name Abstract Method Description
Supplier<T> T get() T 객체λ₯Ό 리턴
BooleanSupplier Boolean getAsBoolean() Boolean 값을 리턴
DoubleSupplier double getAsDouble() double 값을 리턴
IntSupplier int getAsInt() int 값을 리턴
LongSupplier long getAsLong() long 값을 리턴

Supplier<T> μΈν„°νŽ˜μ΄μŠ€λ₯Ό νƒ€κ²Ÿ νƒ€μž…μœΌλ‘œ ν•˜λŠ” λžŒλ‹€μ‹μ€ λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆλ‹€.

IntSupplier supplier = () -> {
  /* statement */
  return int_value;
}

λ‹€μŒ μ˜ˆμ œλŠ” μ£Όμ‚¬μœ„μ˜ 숫자λ₯Ό λžœλ€ν•˜κ²Œ κ³΅κΈ‰ν•˜λŠ” IntSupplier μΈν„°νŽ˜μ΄μŠ€λ₯Ό νƒ€κ²ŸμœΌλ‘œ ν•˜λŠ” λžŒλ‹€μ‹μ΄λ‹€.

public static void main(String[] args) {
  IntSupplier intSupplier = () -> {
    int num = (int) (Math.random() * 6) + 1;

    return num;
  }

  int num = intSupplier.getAsInt();
  System.out.println("눈의 수 : " + num);
}

Function

Function μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•μ€ λ§€κ°œκ°’μ΄ 리턴값이 μžˆλŠ” apply 둜 μ‹œμž‘ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€.
이 λ©”μ„œλ“œλ“€μ€ λ§€κ°œκ°’μ„ λ¦¬ν„΄κ°’μœΌλ‘œ λ§€ν•‘ν•˜λŠ” μ—­ν™œμ„ ν•©λ‹ˆλ‹€.

λ§€κ°œλ³€μˆ˜μ™€ 리턴 νƒ€μž…μ— 따라 μ•„λž˜μ™€ 같은 Function μΈν„°νŽ˜μ΄μŠ€κ°€ μž‡λ‹€.

Interface Name Abstract Method Description
Function<T, R> R apply(T t) 객체 T λ₯Ό 객체 R 둜 맀핑
BiFunction<T, U, R> R apply(T t, U u) 객체 T 와 U λ₯Ό 객체 R 둜 맀핑
DoubleFunction<R> R apply(double value) double 을 객체 R 둜 맀핑
IntFunction<R> R apply(int value) int 을 객체 R 맀핑
IntToDoubleFunction double applyAsDouble(int value) int 을 double 둜 맀핑
IntToLongFunction long applyAsLong(int value) int 을 long 으둜 맀핑
LongToDoubleFunction double applyAsDouble(long value) long 을 double 둜 맀핑
LongToIntFunction ins applyAsInt(long value) long 을 int 둜 맀핑
ToDoubleBiFunction<T, U> double applyAsDouble(T t, U u) 객체 T 와 U λ₯Ό double 둜 맀핑
ToDoubleFunction<T> double applyAsDouble(T value) 객체 T λ₯Ό double 둜 맀핑
ToIntBiFunction<T, U> int applyAsDouble(T t, U u) 객체 T 와 U λ₯Ό int 둜 맀핑
ToIntFunction<T> int applyAsDouble(T value) 객체 T λ₯Ό int 둜 맀핑
ToLongBiFunction<T, U> long applyAsDouble(T t, U u) 객체 T 와 U λ₯Ό long 둜 맀핑
ToLongFunction<T> long applyAsDouble(T value) 객체 T λ₯Ό long 둜 맀핑

Function<T, R> μΈν„°νŽ˜μ΄μŠ€λ₯Ό νƒ€κ²Ÿ νƒ€μž…μœΌλ‘œ ν•˜λŠ” λžŒλ‹€μ‹μ€ λ‹€μŒκ³Ό 같이 μž‘μ„± κ°€λŠ₯ν•©λ‹ˆλ‹€.

Function<Student, String> function = t -> { return t.getName(); };
Function<Student, String> function = t -> return t.getName();

μ•„λž˜ μ˜ˆμ œλŠ” List 에 μ €μž₯된 Student 객체λ₯Ό ν•˜λ‚˜μ”© κΊΌλ‚΄μ„œ ν‰κ· μ μˆ˜λ₯Ό 좜λ ₯ν•œλ‹€.

class Student {
  private String name;
  private int englishScore;
  private int mathScore;

  public Student(String name, int englishScore, int mathScore) {
      super();
      this.name = name;
      this.englishScore = englishScore;
      this.mathScore = mathScore;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public int getEnglishScore() {
      return englishScore;
  }

  public void setEnglishScore(int englishScore) {
      this.englishScore = englishScore;
  }

  public int getMathScore() {
      return mathScore;
  }

  public void setMathScore(int mathScore) {
    this.mathScore = mathScore;
  }
}
private static List<Student> lint = Arrays.asList(
  new Student("Jolie", 100, 89),
  new Student("Martin", 77, 94),
  new Student("Pierre", 49, 100),
  new Student("Paul", 80, 78)
);

public static double avg(ToIntFunction<Student> function) {
  int sum = 0;

  for (Student std : list ) {
    sum += function.applyAsInt(std);
  }

  double avg = (double) sum / list.size();

  return avg;
}

public static void main(String[] args) {
  double englishAvg = avg(s -> s.getEnglishScore());
  System.out.println("μ˜μ–΄ 평균 점수 : " + englishAvg);

  double mathAvg = avg(s -> s.getMathScore());
  System.out.println("μˆ˜ν•™ 평균 점수 : " + mathAvg);
}
μ˜μ–΄ 평균 점수 : 76.5
μˆ˜ν•™ 평균 점수 : 90.25

Operator

Operator μΈν„°νŽ˜μ΄μŠ€λŠ” Function κ³Ό λ™μΌν•˜κ²Œ λ§€κ°œλ³€μˆ˜μ™€ 리턴값이 μžˆλŠ” apply μ΄λ¦„μœΌλ‘œ μ‹œμž‘ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€.

Interface Name Abstract Method Description
BinaryOperator<T> BiFunction<T, U, R> 의 ν•˜μœ„ μΈν„°νŽ˜μ΄μŠ€ T 와 U λ₯Ό μ—°μ‚° ν›„ R 을 리턴
UnaryOperator<T> Function<T, R> 의 ν•˜μœ„ μΈν„°νŽ˜μ΄μŠ€ T λ₯Ό μ—°μ‚°ν•œ ν›„ R 을 리턴
DoubleBinaryOperator double applyAsDouble(double, double) λ‘κ°œμ˜ double 을 μ—°μ‚°
DoubleUnaryOperator double applyAsDouble(double) ν•œκ°œμ˜ double 을 μ—°μ‚°
IntBinaryOperator int applyAsInt(int, int) λ‘κ°œμ˜ int 을 μ—°μ‚°
IntUnaryOperator int applyAsInt(int) ν•œκ°œμ˜ int λ₯Ό μ—°μ‚°
LongBinaryOperator long applyAsLong(long, long) 두 개의 long 을 μ—°μ‚°
LongUnaryOperator long applyAsLong(long) ν•œ 개의 long 을 μ—°μ‚°

λ‹€μŒμ€ int[] λ°°μ—΄μ˜ μ΅œλŒ€κ°’κ³Ό μ΅œμ†Œκ°’μ„ μ–»μŠ΅λ‹ˆλ‹€.

private static int[] scores = {100, 92, 81, 78, 88, 96, 55, 94};

public static int compareNum(IntBinaryOperator operator) {
  int result = scores[0];

  for (int score : scores) {
    result = operator.applyAsInt(result, score);
  }

  return result;
}

public static void main(String[] args) {
  int max = compareNum((a, b) -> (a >= b ? a : b));
  System.out.println("μ΅œλŒ€κ°’ : " + max);

  int min = compareNum((a, b) -> (a <= b ? a : b));
  System.out.println("μ΅œμ†Ÿκ°’ : " + min);
}

λ‹€μŒμ€ replaceAll(UnaryOperator operator) 을 μ΄μš©ν•œ λ¬Έμžμ—΄μ„ concatenate μ—°μ‚° 과정이닀.

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEach {
  public static void main(String[] args) {
    List<Person> list = new ArrayList<>();
    list.add(new Persion(1, "KIM"));
    list.add(new Persion(2, "LEE"));
    list.add(new Persion(3, "PARK"));

    Consumer<Person> style = (Person p) -> System.out.println("id: " + p.getPid() + ", Name: " + p.getName());

    UnaryOperator<Person> unaryOpt = pn -> pn.getName(pn.getName().concat(" -God"));
    list.replaceAll(unaryOpt);

    list.forEach(style);
  }
}
id:1, Name:KIM -God
id:2, Name:LEE -God
id:3, Name:PARK -God

Predicate

Predicate μΈν„°νŽ˜μ΄μŠ€λŠ” λ§€κ°œλ³€μˆ˜μ™€ boolean 리턴값이 있으며 test 둜 μ‹œμž‘ν•˜λŠ” λ©”μ„œλ“œ λͺ…을 가지고 μžˆλ‹€.
이 λ©”μ„œλ“œλŠ” λ§€κ°œκ°’μ„ μ‘°μ‚¬ν•΄μ„œ true ν˜Ήμ€ false 을 λ¦¬ν„΄ν•˜λŠ” μ—­ν™œμ„ ν•œλ‹€.

λ§€κ°œλ³€μˆ˜νƒ€μž…κ³Ό μˆ˜μ— λ”°λΌμ„œ μ•„λž˜μ™€ 같은 Predicate ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 가지고 μžˆλ‹€.

Interface Name Abstract Method Description
Predicate<T> Boolean test(T t) 객체 T λ₯Ό 쑰사
BiPredicate<T, U> Boolean test(T t, U u) 객체 T 와 U λ₯Ό 쑰사
DoublePredicate Boolean test(double value) double 값을 쑰사
IntPredicate Boolean test(int value) int 값을 쑰사
LongPredicate Boolean test(long value) long 값을 쑰사

λ‹€μŒμ€ removeIf() 을 μ΄μš©ν•œ 값을 리슀트λ₯Ό μ œκ±°ν•˜λŠ” μ†ŒλΉ„μžμ˜ μ½”λ“œμ΄λ‹€. (removeIf(Predicate<? super E> filter))

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ForEach {
  public static void main(String[] args) {
    List<Person> list = new ArrayList<>();
    list.add(new Persion(1, "KIM"));
    list.add(new Persion(2, "LEE"));
    list.add(new Persion(3, "PARK"));

    Consumer<Person> style = (Person p) -> System.out.println("id: " + p.getPid() + ", Name: " + p.getName());

    int pid = 2;
    Predicate<Person> predicate = p -> p.getPid() == pid;

    list.removeIf(predicate);

    list.forEach(style);
  }
}
id:1, Name:KIM
id:3, Name:PARK

andThen() κ³Ό compose() 의 λ””ν΄νŠΈ λ©”μ„œλ“œ

andThen() κ³Ό compose() λ©”μ„œλ“œλŠ” λ‘κ°œμ˜ Functional Interface λ₯Ό 순차적으둜 μ—°κ²°ν•˜κ³  첫번째 처리 κ²°κ³Όλ₯Ό λ‘λ²ˆμ§Έ λ§€κ°œκ°’μœΌλ‘œ μ „λ‹¬ν•˜μ—¬ μ΅œμ’… 결과값을 μ–»μ„λ•Œ μ‚¬μš©ν•œλ‹€.

andThen() κ³Ό compose() λ©”μ„œλ“œλŠ” μ²˜λ¦¬μˆœμ„œμ— 따라 λ‹€λ₯΄λ‹€.

InterfaceAB = InterfaceA.compose(Interface B)
Output = InterfaceAB.method()
InterfaceAB = InterfaceA.compose(Interface B)
Output = InterfaceAB.method()
Types Functional Interface andThen() compose()
Consumer Consumer<T> O
BiConsumer<T, U> O
DoubleConsumer O
IntConsumer O
LongConsumer O
Function Function<T, R> O O
BiFunction<T, U, R> O
Operator BinaryOperator<T> O
DoubleUnaryOperator O O
IntUnaryOperator O O
LongUnaryOperator O O

and() or() negate() λ””ν΄νŠΈ λ©”μ†Œλ“œμ™€ isEqual() 정적 λ©”μ†Œλ“œ

두 개 μ΄μƒμ˜ Predicate 연산을 μƒμ„±ν•©λ‹ˆλ‹€.

public static void main(String[] args) {
  IntPredicate predicateA = a -> a % 2 == 0;
  IntPredicate predicateB = b -> b % 3 == 0;

  boolean result;
  IntPredicate predicateAB = predicateA.and(predicateB);
  result = predicateAB.test(9);
  System.out.println("9λŠ” 2와 3의 λ°°μˆ˜μž…λ‹ˆκΉŒ? : " + result);

  predicateAB = predicateA.or(predicateB);
  result = predicateAB.test(9);
  System.out.println("9λŠ” 2λ˜λŠ” 3의 λ°°μˆ˜μž…λ‹ˆκΉŒ? : " + result);

  predicateAB = predicateA.negate();
  result = predicateAB.test(9);
  System.out.println("9λŠ” ν™€μˆ˜μž…λ‹ˆκΉŒ? : " + result);
}

λ‹€μŒμ€ isEquals() λ₯Ό μ΄μš©ν•œ λ¬Έμžμ—΄ 비ꡐ이닀.

public static void main(String[] args) {
  Predicate<String> predicate;

  predicate = Predicate.isEqual(null);
  System.out.println("null, null: " + predicate.test(null));

  predicate = Predicate.isEqual("Java");
  System.out.println("Java, null: " + predicate.test(null));

  predicate = Predicate.isEqual(null);
  System.out.println("null, Java: " + predicate.test("Java"));

  predicate = Predicate.isEqual("Java");
  System.out.println("Java, Java: " + predicate.test("Java"));
}
null, null: true
Java, null: false
null, Java: false
Java, Java: true

참고자료

https://palpit.tistory.com/674