java/함수형 프로그래밍
[Java] Consumer
잘할수있을거야
2022. 3. 13. 19:31
Consumer<T>
@FunctionalInterface
public interface Consumer<T> {
//T 타입 객체의 특정 작업만 수행
void accept(T t);
//현재 Consumer의 accept메서드가 실행되고
//바로 다음으로 인자로 받은 Consumer의 accept메서드가 실행되는 내용이 구현된
//(accept메서드에 구현) 새로운 Consumer 객체 리턴
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer<T>
accept 메서드의 파라메터 타입 - T
andThen의 리턴 타입 - Consumer<T> (<- 동일)
accept
지네릭 타입 T 객체를 받아 T에 대한 특정 작업을 수행하는 메서드
package functionalstudy;
import java.util.function.Consumer;
class Person {
private String name = null;
private int age = 0;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class TestProgram {
public static void main(String[] args) {
Consumer<Person> consumerPerson = p -> {
p.setName("홍길동");
p.setAge(40);
};
Person person = new Person();
consumerPerson.accept(person);
System.out.println(person.getName());
System.out.println(person.getAge());
}
}
andThen
여러 Consumer 객체의 accept메서드가 연쇄적으로 호출되도록 구현된 accept메서드를 가진 Consumer 구현객체 리턴
age 작업을 하는 Consumer와 name 작업을 하는 Consumer로 분리
andThen을 사용하지 않은 경우
public class TestProgram {
public static void main(String[] args) {
Consumer<Person> consumerName = p -> p.setName("홍길동");
Consumer<Person> consumerAge = p -> p.setAge(40);
Person person = new Person();
consumerName.accept(person);
consumerAge.accept(person);
System.out.println(person.getName());
System.out.println(person.getAge());
}
}
andThen을 사용한 경우
public class TestProgram {
public static void main(String[] args) {
Consumer<Person> consumerName = p -> p.setName("홍길동");
Consumer<Person> consumerAge = p -> p.setAge(40);
//consumerName.accept(person)작업 후 consumerAge.accept(person)작업
Consumer<Person> consumerNameThenAge = consumerName.andThen(consumerAge);
Person person = new Person();
//연쇄작업이 accept메서드에 구현된 Consumer의 accept 호출(Person 객체를 넘기면서)
consumerNameThenAge.accept(person);
System.out.println(person.getName());
System.out.println(person.getAge());
}
}
andThen의 Consumer<? super T> (와일드 카드 하한 제한)
package functionalstudy;
import java.util.function.Consumer;
class A {
void aMethod() {
System.out.println("A 작업");
}
}
class B extends A {
void bMethod() {
System.out.println("B 작업");
}
}
class C extends B {
void cMethod() {
System.out.println("C 작업");
}
}
public class TestProgram {
public static void main(String[] args) {
// A타입을 처리하는 consumerA
Consumer<A> consumerA = a -> {
a.aMethod();
System.out.println("consumerA 작업 끝");
System.out.println();
};
// B타입을 처리하는 consumerB
Consumer<B> consumerB = b -> {
b.bMethod();
b.aMethod();
System.out.println("consumerB 작업 끝");
System.out.println();
};
// C타입을 처리하는 consumerC
Consumer<C> consumerC = c -> {
c.cMethod();
c.bMethod();
c.aMethod();
System.out.println("consumerC 작업 끝");
System.out.println();
};
// C인스턴스는 B의 subclass이므로 consumerB에 의해 처리될 수 있다.
Consumer<C> consumerCandThenB = consumerC.andThen(consumerB);
consumerCandThenB.accept(new C());
System.out.println("---------------------------------");
// C인스턴스는 A의 subclass이므로 consumerA에 의해 처리될 수 있다.
Consumer<C> consumerCandThenA = consumerC.andThen(consumerA);
consumerCandThenA.accept(new C());
System.out.println("---------------------------------");
// Consumer<B>의 accept에 B타입을 받으므로 C를 대입도 문제없다.
Consumer<B> consumerBandThenA = consumerB.andThen(consumerA);
consumerBandThenA.accept(new C());
System.out.println("---------------------------------");
}
}