본문 바로가기
Study/Java_study

Java_study_15 (람다식)

by hjshims 2021. 9. 27.

♨학습내용

더보기

람다식 사용법

함수형 인터페이스

 Variable Capture

메서드, 생성자 레퍼런스

 

  • 람다식 사용법
  • 람다식 이란?

- 람다식은(Lambda Expression)은 메서드를 하나의 '식(expression)'으로 표현한 것이다.

- 함수를 간략하게 하면서 명확한 식으로 표현할 수 있게 해 준다.

- 메서드를 람다식으로 표현하면 메서드의 이름과 반환 값이 없어지므로, 람다식을 '익명 함수(anonymous function)'이라고도 한다.
- 자바 8부터 지원되는 기능이다.

 

- 람다식 장점

1. 코드가 간결해진다.

2. 컬렉션 요소(대용량 데이터)를 필터링 혹은 매핑하여 쉽게 데이터의 집계가 가능하다.

 

- 람다식 단점

1. 일정 수준을 넘어가면 가독성이 별로다.

2. 익숙하지 않으면 헷갈릴 수 있다.

 

  • 람다식 사용조건

- 인터페이스만 사용 가능

- 단 한개의 추상 메서드만 정의하는 인터페이스로써 함수형 인터페이스라고 한다.

- @FunctionalInterface 어노테이션을 사용하여 두 개 이상의 메서드가 정의되면 에러를 발생 시킬 수 있다.

 

- 인터페이스 구현 방식은 여러가지가 있다.

  1. 구현 클래스를 사용
  2. 익명함수 사용
  3. 람다 사용

 


 

 

  • 람다식 사용법
  • 구현 클래스 사용

- 재활용하는 용도가 아닌 클래스라면 구현 클래스를 만드는 것은 복잡도를 증가시킨다.

 

- interface 정의

 

public interface MaxNumber {

    int getMaxNumber(int x, int y);
    
}

 

- 구현 클래스 구현

 

public class MaxNumberImpl implements MaxNumber {

    @Override
    public int getMaxNumber(int x, int y) {
        return Math.max(x, y);
    }
}

 

- 사용

 

public class Main {

    public static void main(String[] args) {
        MaxNumber maxNumber = new MaxNumberImpl();

        System.out.println(maxNumber.getMaxNumber(3, 1));
    }
}

 

  • 익명함수 사용

- 구현 클래스를 작성하는 것 보다 간단하지만 형식이 복잡하다.

 

public class Main {

    public static void main(String[] args) {
        MaxNumber maxNumber = new MaxNumber() {
            @Override
            public int getMaxNumber(int x, int y) {
                return Math.max(x, y);
            }
        };

        System.out.println(maxNumber.getMaxNumber(3, 1));
    }
}

 

  • 람다식 사용

- 단 한줄에 간결한 코드를 사용하여 변환 가능하다.

 

public class Main {

    public static void main(String[] args) {
        MaxNumber maxNumber = (x, y) -> Math.max(x, y);

        System.out.println(maxNumber.getMaxNumber(3, 1));
    }
}

 

 


 

 

  • 함수형 인터페이스

- 함수형 인터페이스는 오직 하나의 추상 메서드만 지정하며, 자바 8 부터 java.util.function 패키가 있다.

 

  • Function<T, R>

- T를 인수로 받고, R 타입의 객체를 반환하는 apply 추상 메서드를 정의한다.

- 일반적으로 입력을 출력으로 매핑할 때 사용한다.

 

Function<Integer,Integer> function = (num) -> num + 10;
int apply = function.apply(10);

//출력결과 : 20

 

  • Predicate<T>

- T 객체를 받아서 boolean으로 반환

 

Predicate<Integer> predicate = (integer -> integer > 0);
boolean test = predicate.test(10);

//출력결과 : true

 

  • Consumer<T>

- T 객체를 받아서 리턴 타입이 없다.

 

Consumer<Integer> consumer = (integer -> System.out.println(integer + 10));
consumer.accept(10);

//출력결과 : 20

 

  • Supplier<T>

- 파라미터를 받지 않고 리턴 타입만 갖는다.

 

Supplier<String> supplier = () -> "Functional Interface Test";
String result = supplier.get();

//출력결과 : Functional Interface Test

 

 


 

 

  • Variable Capture

- 자바 람다식은 특정 상황에서 람다 본몬 외부에서 선언된 지역 변수의 값을 캡처할 수 있다.

 

public interface LamdaTest {
    public String create (char[] chars);
}

 

public class LocalCapture {
    public static void main(String[] args) {
        String local = "test";
        LamdaTest lamdatest = (chars)-> local + new String(chars);
    }
}

 

- 람다 본문의 외부에 선언된 local 지역 변수를 참조한다.

- 이 경우에 local 변수는 처음으로 값을 할당 받은 이후 값을 변경하지 않아야 한다.

- 만일 값을 변경하게 되면 람다 본문에서 컴파일 에러가 발생한다.

- 보통 이런 일을 막기위해 final 키워드로 상수로 선언해준다.

- 값이 처음으로 할당된 이후 변경될 가능성이 없다면 컴파일러에서 final과 동일하게 취급하기 때문에 가능하다.

 

 

 


 

 

 

  • 메서드, 생성자 레퍼런스

- 람다 표현식을 더욱 간결하게 표현해주는 방법으로 클래스명::메서드명 형식으로 표현한다.

- 메서드의 괄호는 생략 추상 메서드가 오직 하나만 있기에 가능한 방법으로,

- 리턴 타입과 파라미터 타입 추론이 가능하기 때문에 이와 같이 더욱 간결하게 표현 할 수 있다.

 

  • Static 메서드 레퍼런스
// 기본 람다식
(String str) -> Integer.parseInt(str);

// static 메서드 래퍼런스
Integer::parseInt

 

  • 생성자 메서드 레퍼런스
// 기본 람다식
() -> new Integer();

// 생성자 메서드 래퍼런스 
Integer::new

 

  • Instance 메서드 레퍼런스
// 기본 람다식
(String str) -> str.length();

// 인스턴스 메서드 래퍼런스 
String::length

 

 

 

 

'Study > Java_study' 카테고리의 다른 글

Java_study_14 (제네릭)  (0) 2021.09.20
Java_study_13 (I/O)  (0) 2021.09.20
Java_study_12 (애노테이션)  (0) 2021.09.14
Java_study_11 (Enum)  (0) 2021.09.07
Java_study_10 (멀티쓰레드 프로그래밍)  (0) 2021.08.30