람다식 - 표준 함수적 인터페이스
표준 함수적 인터페이스
- 자바에서 제공되는 표준 API에서 한 개의 추상 메서들을 갖는 인터페이스는 람다식을 이용하여 익명 구현 객체로 표현 가능
- ex) Runnable
- 자바 8부터 자주 사용되는 함수적 인터페이스는 java.util.function 패키지로 제공
- 이 패키지의 목적은 메서드 또는 생성자의 매개 타입으로 사용되어 람디식을 대입할 수 있도록 하는 것
- 자바 8부터 추가되거나 변경된 API는 표준 함수적 인터페이스를 매개 타입으로 사용
- 용도에 따라 분류
- Consumer, Supplier, Fuction, Operator, Predicate
Consumer
- 함수적 인터페이스
- 리턴 값이 없는 accept() 메서드를 포함
- accept() 메서드는 매개값을 소비하는 역할
- 사용만 하고 리턴 값이 없음
- Consumer : 한 개의 매개값(제네릭으로 지정된 타입)을 받아 소비
- BiConsumer : 두 개의 매개값을 받아 소비
- DoubleConsumer : 하나의 double 값을 받아 소비
- ObjIntConsumer : 제네릭으로 지정된 타입과 int(정수)의 매개값을 받아 소비(2개)
public class A_Consumer {
public void method1() {
// Consumer
Consumer<String> consumer = (String str) -> {
System.out.println(str);
};
// 타입 생략 가능, 매개값이 하나일 경우 소괄호 생략 가능, 실행문이 하나일 경우 중괄호 생략 가능
// Consuer<Strong> consumer = str -> System.out.println(str);
consumer.accept("Consumer : 한 개의 매개값(제네릭으로 지정된 타입)을 받아 소비");
// BiConsumer
BiConsumer<String, String> biConsumer = (String str1, String str2) -> {
System.out.println(str1 + str2);
};
biConsumer.accept("BiConsumer : ", "두 개의 매개값을 받아 소비");
// DoubleConsumer
DoubleConsumer dConsumer = (value) -> {
System.out.println("DoubleConsumer : 하나의 double 값을 받아 소비. value:" + value);
};
dConsumer.accept(3.14);
// ObjIntConsumer
ObjIntConsumer<String> objIntConsumer = (String str, int i) -> {
System.out.println(str + i);
};
objIntConsumer.accept("objIntConsumer : 제네릭으로 지정된 타입과 int(정수)의 매개값을 받아 소비(2개)", 10);
}
}
Supplier
- 함수적 인터페이스
- 매개변수가 없고 리턴값이 있는 getXXX() 메서드 포함
- 이 메서드는 실행 후 호출한 곳으로 데이터를 리턴(공급)하는 역할
package java.util.function;
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
-
Supplier<String> supplier = () -> {
return "Supplier : 제네릭으로 지정된 타입의 객체를 리턴"; // Supplier<String>
};
System.out.println(supplier.get()); // Supplier 인터페이스에 있는 get메서드 호출
// return값이 하나일 경우 return 키워드 생략 가능
// 실행문이 하나일 경우 중괄호 생략 가능
// Supplier<String> supplier = () -> "Supplier : 제네릭으로 지정된 타입의 객체를 리턴";
-
package java.util.function;
@FunctionalInterface
public interface IntSupplier {
/**
* Gets a result.
*
* @return a result
*/
int getAsInt();
}
-
// 정수값 리턴
IntSupplier intSupplier = () -> {
return 10 + 20;
};
System.out.println(intSupplier.getAsInt());
Function
- 매개변수와 리턴값이 있는 applyXXX() 메서드 포함
- 매개변수를 리턴값으로 매핑(타입 변환) 하는 역할
package com.kh.lambda.standard.model.vo;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private String name;
private int age;
private String gender;
private int math;
private int english;
}
-
public void method1() {
Student student = new Student("홍길동", 10, "남자", 80, 70);
// Student 객체를 받아서 String으로 타입 변환
Function<Student, String> function = s -> s.getName();
System.out.println("이름: " + function.apply(student));
System.out.print("수학 :");
printInt((s) -> s.getMath(), student);
System.out.print("영어 :");
printInt((s) -> s.getEnglish(), student);
System.out.print("평균 :");
printInt((s) -> (s.getMath() + s.getEnglish()) / 2, student);
}
public void printInt(ToIntFunction<Student> function, Student student) {
System.out.println(function.applyAsInt(student));
}
이거 쫌 뭔 말인지 모르겠는데..??
ToIntFunction 이거 갑자기 왜.. 왜 이렇게 헷갈려.
쌤이 ToIntFunction 아직 이거는 생각하지 말라고 하셨음.. 그래도 되나요.
Operator
- 매개변수와 리턴값이 있는 applyXXX() 메서드 포함
- 매개변수를 이용하여 연산하고 동일한 타입으로 결과 리턴
// IntBinaryOperator : 두 개의 정수
IntBinaryOperator IntBinaryOperator = (a, b) -> a * b;
System.out.println(IntBinaryOperator.applyAsInt(10, 20)); // 200
// IntUnaryOperator : 한 개의 정수
IntUnaryOperator IntUnaryOperator = (a) -> a * a;
System.out.println(IntUnaryOperator.applyAsInt(10)); // 100
Predicate
- 매개변수와 boolean 리턴 값이 있는 testXXX() 메서드 포함
- 이 메서드의 매개변수를 확인하여 true/false를 리턴하는 역할
Student student1 = new Student("아이유", 20, "여자", 100, 90);
Student student2 = new Student("유인나", 22, "여자", 80, 100);
Predicate<Student> predicate = student -> {
return student.getGender().equals("남자");
};
System.out.println("아이유는 남자? : " + predicate.test(student1));
어떤 건 이해가 팍 되는데.. 어떤 건 너무 이해가 안 되고..
그런 것도 수업 이후에 다시보면 멘붕의 연속.