Supplier 함수적 인터페이스
Supplier 함수적 인터페이스의 특징은 매개 변수가 없고 리턴값이 있는 getXXX() 메소드를 가지고 있다. 이 메소드들은 실행 후 호출한 곳으로 데이터를 리턴하는 역할을 한다.
리턴 타입에 따라서 아래와 같은 Supplier 함수적 인터페이스들이 있다.
인터페이스명 | 추상 메소드 | 설명 |
Supplier<T> | T get() | T 객체를 리턴 |
BooleanSupplier | boolean getAsBoolean() | boolean 값을 리턴 |
DoubleSupplier | double getAsDouble() | double 값을 리턴 |
IntSupplier | int getAsInt() | int 값을 리턴 |
LongSupplier | long getAsLong() | long 값을 리턴 |
Supplier<T> 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. get() 메소드가 매개값을 가지지 않으므로 람다식도 ( )를 사용한다. 람다식의 중괄호 { }는 반드시 한 개의 T 객체를 리턴하도록 해야 한다. T가 String 타입이므로 람다식의 중괄호 { }는 문자열을 리턴하도록 해야 한다.
Supplier<String> supplier = () -> { ...; return "문자열"; }
IntSupplier 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. getAsInt() 메소드가 매개값을 가지지 않으므로 람다식도 ( )를 사용한다. 람다식의 중괄호 { }는 반드시 int 값을 리턴하도록 해야 한다.
IntSupplier supplier = () -> { ...; return int값; }
다음 예제는 주사위의 숫자를 랜덤하게 공급하는 IntSupplier 인터페이스를 타겟 타입으로 하는 람다식이다.
// SupplierExample.java -- Supplier 함수적 인터페이스
import java.util.function.IntSupplier;
public class SupplierExample {
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 함수적 인터페이스의 특징은 매개값과 리턴값이 있는 applyXXX() 메소드를 가지고 있다. 이 메소드들은 매개값을 리턴값으로 매핑(타입 변환)하는 역할을 한다.
매개 변수 타입과 리턴 타입에 따라서 아래와 같은 Function 함수적 인터페이스들이 있다.
인터페이스명 | 추상 메소드 | 설명 |
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으로 매핑 |
LongToDoubleFucntion | double applyAsDouble(long value) | long을 double로 매핑 |
LongToIntFunction | int applyAsInt(long value) | long을 int로 매핑 |
ToDoubleFunction<T, U> | double applyAsDouble(T t, U u) | 객체 T와 U를 double로 매핑 |
ToDoubleFunction<T> | double applyAsDouble(T t) | 객체 T를 double로 매핑 |
ToIntBiFunction<T, U> | int applyAsInt(T t, U t) | 객체 T와 U를 int로 매핑 |
ToIntFunction<T> | int applyAsInt(T t) | 객체 T를 int로 매핑 |
ToLongBiFunction<T, U> | long applyAsLong(T t, U u) | 객체 T와 U를 long으로 매핑 |
ToLongFunction<T> | long aplyAsLong(T t) | 객체 T를 long으로 매핑 |
Function<T, R> 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. apply() 메소드는 매개값으로 T 객체 하나를 가지므로 람다식도 한 개의 매개 변수를 사용한다. 그리고 apply() 메소드의 리턴 타입이 R이므로 람다식의 중괄호 { }의 리턴값은 R 객체가 된다. T가 Student 타입이고 R이 String 타입이므로 t 매개 변수 타입은 Student가 되고, 람다식의 중괄호 { }는 String을 리턴해야 한다. t.getName()은 Student 객체의 getName() 메소드를 호출해서 학생 이름(String)을 얻는다. return 문만 있을 경우 중괄호 { }와 return 문은 생략할 수 있다는 것을 이미 배웠다. 다음 코드는 Student 객체를 학생 이름(String)으로 매핑하는 것이다.
Fucntion<Student, String> function = t -> { return t.getName(); }
또는
Function<Student, String> function = t -> t.getName();
ToIntFunction<T> 인터페이스를 타겟 타입으로 하는 람다식은 다음과 같이 작성할 수 있다. applyAsInt() 메소드는 메개값으로 T 객체 하나를 가지므로 람다식도 한 개의 매개 변수를 사용한다. 그리고 applyAsInt() 메소드의 리턴 타입이 int이므로 람다식 중괄호 { }의 리턴값은 int가 된다. T가 Student 타입이므로 t 매개 변수 타입은 Student가 된다. t.getScore()는 Student 객체의 getScore() 메소드를 호출해서 학생 점수(int)를 얻는다. 다음 코드는 Student 객체를 학생 점수(int)로 매핑하는 것이라고 볼 수 있다.
ToIntFunction<Student> function = t -> { return t.getScore(); }
또는
ToIntFunction<Student> function = t -> t.getScore();
다음 예제는 List에 저장된 학생 객체를 하나씩 꺼내서 이름과 점수를 출력한다. FunctionExample1의 printString() 메소드는 Function<Student, String> 매개 변수를 가지고 있고, printInt() 메소드는 ToIntFunction<Student> 매개 변수를 가지고 있으므로 이 메소드들을 호출할 때 매개값으로 람다식을 사용할 수 있다.
// FucntionExample.java -- Function 함수적 인터페이스
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToIntFunction;
public class FuntionExmaple1 {
private static List<Student> list = Arrays.asList(
new Student("홍길동", 90, 96),
new Student("김자바", 95, 93)
);
public static void printString(Function<Student, String> function) {
for(Student student : list) { // list에 저장된 항목 수만큼 루핑
System.out.print(function.apply(student) + " ");
}
System.out.println();
}
public static void printlnt(ToIntFunction<Student> function) {
for(Student student : List) {
System.out.print(function.applyAsInt(student) + " ");
}
System.out.println();
}
public static void main(String[] args) {
System.out.println("[학생 이름]");
printString(t->t.getName());
System.out.println("[영어 점수]");
printInt(t->t.getEnglishScore());
System.out.println("[수학 점수]");
printInt(t->t.getMathScore());
}
}
// Student.java -- Student 클래스
public class Student {
private String name;
private int englishScore;
private int mathScore;
public Student(String name, int englishScore, int mathScore) {
this.name = name;
this.englishScore = englishScore;
this.mathScore = mathScore;
}
public String getName() { return name; }
public int getEnglishScore() { return englishScore; }
public int getMathScore() { return mathScore; }
다음 예제는 List에 저장된 학생 객체를 하나씩 꺼내서 영어 점수와 수학 점수의 평균값을 산출한다. FunctionExample2의 avg() 메소드는 ToIntFunction<Student> 매개 변수를 가지고 있다. 따라서 avg() 메소드를 호출할 때 매개값으로 람다식을 사용할 수 있다. 람다식은 getEnglishScore()와 getMathScore()를 호출해서 영어 점수와 수학 점수로 Student 객체를 매핑시킨다.
// FunctionExmaple2.java -- Function 함수적 인터페이스
import java.util.Arrays;
import java.util.List;
import java.util.function.ToIntFunction;
public class FunctionExample2 {
private static List<Student> list = Array.asList(
new Student("홍길동", 90, 96),
new Student("김자바", 95, 93)
);
public static double avg( ToIntFunction<Student> function) {
int sum = 0;
for(Student student : List) {
sum += function.applyAsInt(student);
}
double avg = (double) sum / list.size();
return avg;
}
public static void main(String[] args) {
double mathAvg = avg(s -> s.getMathScore());
System.out.println("수학 평균 점수: " + mathAvg);
}
}
'Java 길찾기 > 이것이 자바다' 카테고리의 다른 글
[Java] 표준 API의 함수적 인터페이스 - andThen(), compose() 디폴트 메소드 (0) | 2022.04.19 |
---|---|
[Java] 표준 API의 함수적 인터페이스 - Operator, Predicate (0) | 2022.04.18 |
[Java] 표준 API의 함수적 인터페이스 - Consumer (0) | 2022.04.14 |
[Java] 클래스 멤버와 로컬 변수 사용 (0) | 2022.04.13 |
[Java] 타겟 타입과 함수적 인터페이스 (0) | 2022.04.12 |