자바 스터디
15주차 과제: 람다식
삶은겨란
2022. 6. 17. 03:30
목표
자바의 람다식에 대해 학습하세요.
목차
1. 람다식 사용법
2. 함수형 인터페이스
3. Variable Capture
4. 메소드, 생성자 레퍼런스
1. 람다식 사용법
람다식(익명 함수)
메소드를 하나의 식으로 표현
장점
- 가독성
- 코드 간결성
- 멀티쓰레드
- 실행문을 바로 전달(메소드로 값이나 객체를 생성해 전달하는 방식과 달리 실행문 자체를 전달해 구현)
단점
- 람다식을 너무 많이 사용하면 가독성이 떨어짐
- 재사용 불가
사용법
(매개변수) -> {실행문}
() -> // 실행문이 단일일 경우 {}생략 가능. return이 있으면 {}가 있어야 한다
// 함수로 작성한 덧셈
public int sum(int a, int b){
return a+b;
}
// 람다식으로 작성한 덧셈
(a, b) -> a+b;
2. 함수형 인터페이스
람다식은 함수형 인터페이스로 접근이 가능하다.
더보기
함수형 인터페이스는 추상 메소드가 하나인 인터페이스
@FunctionalInterface : 함수형 인터페이스 조건에 맞는지 검사해주는 어노테이션
@FunctionalInterface
public interface Car {
void number(); // 추상 메소드
static void printName(){
System.out.println("sonata");
}
default void printColor(){
System.out.println("black");
}
}
추상 메소드가 하나만 있으므로 함수형 인터페이스이다.
자주 사용하는 함수형 인터페이스
- Supplier<T>: 인자가 없고 T타입을 리턴
@FunctionalInterface
interface Supplier<T> {
T get();
}
public class Ex {
public static void main(String[] args) {
Supplier<String> supplier= ()-> "hello";
String result = supplier.get();
System.out.println(result);
}
}
- Consumer<T>: T타입을 받아 실행. 리턴값이 없다.
@FunctionalInterface
interface Consumer<T> {
void accept(T t);
}
public class Ex {
public static void main(String[] args) {
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("hello");
}
}
- Function<T, R> : T타입을 받아 R타입을 반환
@FunctionalInterface
interface Function<T, R> {
R apply(T a, T b);
}
public class Ex {
public static void main(String[] args) {
Function<Integer, Integer> sum= (a,b)-> a+b;
int result = sum.apply(3,6);
System.out.println(result);
}
}
- Predicate<T>: T타입을 받아 boolean을 리턴
@FunctionalInterface
interface Predicate<T> {
boolean test(T t);
}
public class Ex {
public static void main(String[] args) {
Predicate<Integer> positive = num -> num > 0;
System.out.println(positive.test(1));
}
}
3. Variable Capture
variable capture, lambda capturing
람다식에서 외부 지역변수를 참조
특징
- final로 선언되거나 final 처럼 동작되어야 한다.
- 람다식보다 먼저 할당해야 한다.
interface MyInterface {
void myFunction();
}
public class Ex {
int data = 100;
public static void main(String[] args)
{
Ex test = new Ex();
MyInterface intFace = () ->
{
System.out.println("Data : " + test.data);
test.data += 10;
System.out.println("Data : " + test.data);
};
intFace.myFunction();
test.data += 10;
System.out.println("Data : " + test.data);
}
}
4. 메소드, 생성자 레퍼런스
메소드 참조(Method Reference)
람다식이 하나의 메소드만 호출할 때 매개변수 없이 사용할 수 있도록 해준다.
메소드 참조는 람다식의 단일 메소드를 대체하는 데만 사용할 수 있다.
클래스이름 or 참조변수이름::메소드이름
list.forEach(s) -> System.out.println(s)); // 람다식
list.forEach(System.out::println); // 메소드 참조
메소드 참조 유형
- static 메소드 참조
(args) -> Class.staticMethod(args) // 람다식이 클래스의 정적 메소드를 호출하는 경우
Class::staticMethod // 메소드 참조로 대체
- 인스턴스 메서드 참조
(인수) -> obj.instanceMethod(인수) // 람다식이 객체의 기본 메소드를 호출하는 경우
obj::인스턴스 메서드
- 특정 유형의 임의 개체에 대한 인스턴스 메서드 참조
(obj, args) -> obj.instanceMethod(args) // 람다식이 ObjectType의 인스턴스 메소드를 호출하는 경우
ObjectType::instanceMethod
- 생성자 참조
(args) -> new ClassName(args) // 람다식이 객체를 생성하는 경우
ClassName::new
https://www.geeksforgeeks.org/java-lambda-expression-variable-capturing-with-examples/?ref=gcse
https://www.geeksforgeeks.org/method-references-in-java-with-examples/?ref=gcse