본문 바로가기
JAVA

Functional Interface 파고들기 - Predicate, Consumer, Supplier +

by HCastle 2022. 5. 2.
반응형

이번 글에서는 java.util.function package 에 있는 Functional Interface 중 Predicate, Consumer, Supplier 인터페이스 및 변형 인터페이스들에 대해서 정리해보려고 합니다.

 

대상 목록은 아래와 같습니다.

 

Interface Type Functional Method Description
Predicate<T> boolean test(T t) 단일 입력을 받아 boolean 결과값 반환
BiPredicate<T,U> boolean test(T t, U u) 두 입력을 받아 boolean 결과값 반환
IntPredicate boolean test(int value) int 입력을 받아 boolean 결과값 반환
LongPredicate boolean test(long value) long 입력을 받아 boolean 결과값 반환
DoublePredicate boolean test(double value) double 입력을 받아 boolean 결과값 반환
Consumer<T> void accept(T t) 단일 입력을 받아 결과값을 반환 하지 않음
BiConsumer<T,U> void accept(T t, U u) 두 입력을 받아 결과값을 반환 하지 않음
IntConsumer void accept(int value) int 입력을 받아 결과값을 반환 하지 않음
LongConsumer void accept(long value) long 입력을 받아 결과값을 반환 하지 않음
DoubleConsumer void accept(double value) double 입력을 받아 결과값을 반환 하지 않음
ObjIntConsumer<T> void accept(T t, int value) Object 값과 int 값 입력을 받아 결과값을 반환 하지 않음
ObjLongConsumer<T> void accept(T t, long value) Object 값과 long 값 입력을 받아 결과값을 반환 하지 않음
ObjDoubleConsumer<T> void accept(T t, double value) Object 값과 double 값 입력을 받아 결과값을 반환 하지 않음
Supplier<T> T get() 입력값 없이 T 객체를 반환
BooleanSupplier boolean getAsBoolean() 입력값 없이 Boolean 객체를 반환
IntSupplier int getAsInt() 입력값 없이 Int 객체를 반환
LongSupplier long getAsLong() 입력값 없이 Long 객체를 반환
DoubleSupplier double getAsDouble() 입력값 없이 Double 객체를 반환

 

 

Predicate

Predicate 관련 인터페이스는 입력을 받아 boolean Type 의 값을 반환해주는 interface 입니다.

Predicate
<CODE>
private List<StudentDTO> getStudents() {
    List<StudentDTO> students = new ArrayList<>();
    students.add(new StudentDTO("Willy", 23, 93, 84));
    students.add(new StudentDTO("Jane", 25, 71, 97));
    students.add(new StudentDTO("James", 21, 88, 89));

    return students;
}

private void predicate() {
    List<StudentDTO> students = getStudents();
    StudentDTO studentWilly = students.get(1); // Willy
    Predicate<StudentDTO> predMath = (a) -> a.getScoreMath() >= 85;
    System.out.println("Predicate test, negate, not, isEqual");
    for (StudentDTO student : students) {
        System.out.println("Predicate Math:" + predMath.test(student)
                + ", negate:" + predMath.negate().test(student)
                + ", not:" + Predicate.not(predMath).test(student)
                + ", isEqual:" + Predicate.isEqual(studentWilly).test(student)
                + " - " + student.toString());
    }

    System.out.println("Predicate and");
    for (StudentDTO student : students) {
        System.out.println("Predicate Math:" + predMath.and((a) -> a.scoreEnglish >= 85).test(student) + " - " + student.toString());
    }

    System.out.println("Predicate or");
    for (StudentDTO student : students) {
        System.out.println("Predicate Math:" + predMath.or((a) -> a.scoreEnglish >= 85).test(student) + " - " + student.toString());
    }
}


<OUTPUT>
Predicate test, negate, not, isEqual
Predicate Math:true, negate:false, not:false, isEqual:false - name:Willy, age:23, scoreMath:93, scoreEnglish:84
Predicate Math:false, negate:true, not:true, isEqual:true - name:Jane, age:25, scoreMath:71, scoreEnglish:97
Predicate Math:true, negate:false, not:false, isEqual:false - name:James, age:21, scoreMath:88, scoreEnglish:89
Predicate and
Predicate Math:false - name:Willy, age:23, scoreMath:93, scoreEnglish:84
Predicate Math:false - name:Jane, age:25, scoreMath:71, scoreEnglish:97
Predicate Math:true - name:James, age:21, scoreMath:88, scoreEnglish:89
Predicate or
Predicate Math:true - name:Willy, age:23, scoreMath:93, scoreEnglish:84
Predicate Math:true - name:Jane, age:25, scoreMath:71, scoreEnglish:97
Predicate Math:true - name:James, age:21, scoreMath:88, scoreEnglish:89


<설명>
- boolean test(T t) : functional method
  > 인수 t 를 입력받아 평가하여 boolean 값을 반환합니다.
- default Predicate<T> negate()
  > predicate 의 논리적 반대값을 반환하는 Predicate 객체를 반환합니다.
- static <T> Predicate<T> not(Predicate<? super T> target)
  > negate() 와 같지만 static 메소드 입니다.
- static <T> Predicate<T> isEqual(Object targetRef)
  > static 메소드이며 targetRef 와 test(T t)의 인수 t 에 대해 Objects.equals(Object, Object) 를 수행합니다.
- default Predicate<T> and(Predicate<? super T> other)
  > other 의 입력 값과 test(T t) 의 인수 t 에 대해 논리적 AND 평가를 하여 boolean 값을 반환합니다.
- default Predicate<T> or(Predicate<? super T> other)
  > other 의 입력 값과 test(T t) 의 인수 t 에 대해 논리적 OR 평가를 하여 boolean 값을 반환합니다.

 

BiPredicate
<CODE>
List<StudentDTO> students = getStudents();
BiPredicate<Integer, Integer> biPredTot = (a, b) -> (a + b) > 170;
System.out.println("BiPredicate test, negate, and, or");
for (StudentDTO student : students) {
    System.out.println("BiPredicate test:" + biPredTot.test(student.getScoreMath(), student.getScoreEnglish())
            + ", negate:" + biPredTot.negate().test(student.getScoreMath(), student.getScoreEnglish())
            + ", and:" + biPredTot.and((a, b) -> a > 85 && b > 85).test(student.getScoreMath(), student.getScoreEnglish())
            + ", or:" + biPredTot.or((a, b) -> a > 95 || b > 95).test(student.getScoreMath(), student.getScoreEnglish())
            + " - " + student.toString());
}


<OUTPUT>
BiPredicate test, negate, and, or
BiPredicate test:true, negate:false, and:false, or:true - name:Willy, age:23, scoreMath:93, scoreEnglish:84
BiPredicate test:false, negate:true, and:false, or:true - name:Jane, age:25, scoreMath:71, scoreEnglish:97
BiPredicate test:true, negate:false, and:true, or:true - name:James, age:21, scoreMath:88, scoreEnglish:89


<Method>
R apply(T t, U u) : functional method
  > t, u 를 입력값으로 받아 R Type 의 결과값을 반환합니다.
- default <V> BiFunction<T,U,V> andThen(Function<? super R, ? extends V> after)
  > apply method 이후에 수행되며 apply 의 결과 값(R Type)을 인수로 받는 after function 을 수행합니다.

- boolean test(T t, U u) : functional method
  > 인수 t, u 를 입력받아 평가하여 boolean 값을 반환합니다.
- default BiPredicate<T,U> negate()
  > predicate 의 논리적 반대값을 반환하는 BiPredicate 객체를 반환합니다.
- default BiPredicate<T> and(BiPredicate<? super T,? super U> other)
  > other 와 biPredicate 의 논리적 AND 평가를 하여 boolean 값을 반환합니다.
- default BiPredicate<T> or(BiPredicate<? super T,? super U> other)
  > other 와 biPredicate 의 논리적 OR 평가를 하여 boolean 값을 반환합니다.

 

 

Consumer

Consumer 는 결과값을 반환하지 않고 입력값에 대한 처리만을 담당하는 functional interface 입니다.

특이점으로는 결과값을 반환하지 않기 때문에 default method 와 결과값이 아닌 입력값을 공유합니다.

 

Consumer
<CODE>
List<StudentDTO> students = getStudents();
Consumer<StudentDTO> consumer = (a) -> System.out.print(a.getName());
System.out.println("Consumer accept, andThen");
for (StudentDTO student : students) {
    System.out.print("Consumer accept:");
    consumer.accept(student);
    System.out.print(" andThen:");
    consumer.andThen((a) -> System.out.println("'s " + a.getAge() + " years old")).accept(student);
}


<OUTPUT>
Consumer accept, andThen
Consumer accept:Willy andThen:Willy's 23 years old
Consumer accept:Jane andThen:Jane's 25 years old
Consumer accept:James andThen:James's 21 years old


<Method>
- void accept(T t) : functional method
  > t 를 입력받아 처리합니다.
- default Consumer<T> andThen(Consumer<? super T> after)
  > consumer 를 수행한 이후 동일한 입력값을 after 에 입력받아 처리합니다.

 

 

BiConsumer
<CODE>
List<StudentDTO> students = getStudents();
BiConsumer<String, Integer> biConsumer = (a, b) -> System.out.print("name:" + a + ", age:" + b);
System.out.println("BiConsumer accept, andThen");
for (StudentDTO student : students) {
    System.out.print("BiConsumer accept:");
    biConsumer.accept(student.getName(), student.getAge());
    System.out.print(" andThen:");
    biConsumer.andThen((a, b) -> System.out.println(" " + a + "'s age:" + b)).accept(student.getName(), student.getAge());
}


<OUTPUT>
BiConsumer accept, andThen
BiConsumer accept:name:Willy, age:23 andThen:name:Willy, age:23 Willy's age:23
BiConsumer accept:name:Jane, age:25 andThen:name:Jane, age:25 Jane's age:25
BiConsumer accept:name:James, age:21 andThen:name:James, age:21 James's age:21


<Method>
- void accept(T t, U u) : functional method
  > t, u 를 입력받아 처리합니다.
- default BiConsumer<T,U> andThen(Consumer<? super T,? super U> after)
  > biConsumer 를 수행한 이후 동일한 입력값을 after 에 입력받아 처리합니다.

 

 

Supplier

Supplier 는 Consumer 와 반대로 입력값은 없고 결과값만 반화하는 interface 입니다.

 

Supplier
<CODE>
Supplier<StudentDTO> supplier = () -> new StudentDTO();
System.out.println(supplier.get().getClass());


<OUTPUT>
class c.part6.chapter33.StudentDTO


<Method>
- T get() : functional method
  > 입력값 없이 결과값을 반환합니다.

 

반응형

댓글