배경
람다식(Lambda Expressions)
interface InterfaceExample {
int CONSTANT = 3;
default void printTest() {};
}
// 익명 내부 클래스
InterfaceExample interfaceExample = new InterfaceExample() {
public void printTest() {...}
}
// 람다식 : (매개변수) -> {실행코드} 형태
// InterfaceExample의 익병 구현 객체 생성
InterfaceExample interfaceExample = () -> {...}
// 1. 기본 작성
(타입 매개변수) -> { ... }
// 2. 매개변수가 1개 일 때, 매개변수 () 생략가능
매개변수 -> { ... }
// 3. 매개변수가 2개 이상이고, 리턴문만 존재할 때는 return을 생략가능
(매개변수1, 매개변수2) -> 리턴값;
(num1, num2) -> {return num1 + num2} // return문만 존재하므로
(num1, num2) -> num1 + num2 // return문만 있을 경우, return 생략가능, 중괄호도 생략
// 4. 매개변수가 2개 이상이고, 실행문을 실행하고 결과값을 리턴할 경우
(매개변수1, 매개변수2) -> { ... };
@FunctionalInterface // 두 개 이상의 추상 메서드가 선언되면 컴파일 오류를 발생
InterfaceExample interfaceExample = new InterfaceExample() {
public void printTest() {...}
}
public class LambdaExample {
public static void main(String[] args) {
Printsometh printsometh;
printsometh = () -> System.out.println("sout first");
printsometh.print(); // sout first
printsometh = () -> {
String string = "sout second";
System.out.println(string);
};
printsometh.print(); // sout second
Multiply multiply;
multiply = (num1, num2) -> num1*num2;
System.out.println(multiply.cal(3,4)); // 12
multiply = ((num1, num2) -> {return num1*num2;});
System.out.println(multiply.cal(3,4)); // 12
}
}
@FunctionalInterface
interface Printsometh{
void print();
}
@FunctionalInterface
interface Multiply{
int cal(int num1, int num2);
}
목적 : 불필요한 매개변수를 제거하여 람다식 표현
IntBinaryOperator operato = (left, right) -> Math.max(left, right);
//예시 : 단순히 두 개의 값을 Math.max() 메서드의 매개값으로 전달하는 역할만 하기 때문에 다소 불편힘
// 메서드 레퍼런스 사용
IntBinaryOperator operato = Math :: max;
메서드 레퍼런스 종류
class Calculator {
static int staticMethod(int x, int y) {
return x + y;
}
int instanceMethod(int x, int y) {
return x * y;
}
}
public class MethodReferences {
public static void main(String[] args) throws Exception {
IntBinaryOperator operator;
//static method
operator = Calculator::staticMethod; // 클래스 이름을 이용
System.out.println("정적메서드 결과 : " + operator.applyAsInt(3, 5));
// 정적메서드 결과 : 8
//instance method
Calculator calculator = new Calculator();
operator = calculator::instanceMethod; // 만든 인스턴스의 참조 변수를 이용
System.out.println("인스턴스 메서드 결과 : "+ operator.applyAsInt(3, 5));
// 인스턴스 메서드 결과 : 15
// operator = calculator::staticMethod;
// 정적 메세드를 참조 변수를 이용해 레퍼런스를 하면 에러!
}
}
public class ParameterMethodReferenceExample {
public static void main(String[] args) {
Equal equal = ((str1, str2) -> str1.equals(str2));
System.out.println(equal.equal("1","1")); // true
equal = String::equals;
System.out.println(equal.equal("1","1")); // true
}
}
@FunctionalInterface
interface Equal{
boolean equal(String str1, String str2);
}
public class ConstructorRef {
public static void main(String[] args) throws Exception {
Function<String, Member> function1 = Member::new;
Member member1 = function1.apply("kimcoding");
// Member(String id) 실행
BiFunction<String, String, Member> function2 = Member::new;
Member member2 = function2.apply("kimcoding", "김코딩");
// Member(String name, String id) 실행
}
}
public class Member {
public Member(String id) {
System.out.println("Member(String id) 실행");
this.id = id;
}
public Member(String name, String id) {
System.out.println("Member(String name, String id) 실행");
this.id = id;
this.name = name;
}
}