자바 스터디

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