JAVA 람다식 (1)

yscho·2023년 9월 21일
0
post-thumbnail

코딩테스트를 준비하며.....

java를 메인 언어로 공부하는 입장에서
각종 알고리즘 문제풀이 사이트에서 순위권에 존재하는 코드를 구경하다 보면
내가 알던 자바가 맞나? 싶을 정도로 간결하고 가독성이 높은 코드들을 마주할 때가 있다.

단순히 for문과 if문을 사용하던 아니, 전부인줄 알았던 나에겐 신선한 충격이였다.

지금까지 람다식과 스트림을 몰랐던 내가 더 충격...

아무튼 람다와 스트림에 대하여 검색을 좀 해보니 Java8 부터 시작된 문법이였고 현업에서 많~이 사용한다는 사실을 알게 되었다.

이번 기회에 람다와 스트림 문법을 장착하여 코드를 모던하게 작성 해보겠다.


람다식

람다식을 한 마디로 정의하자면

" 메서드를 한 하나의 식으로 표현한 것 "

이라고 할 수 있다.

그렇다면 람다식은 메서드일까? 객체일까?
결론부터 말하자면 람다식은 익명 "객체"이다.

객체를 다루려면 참조변수가 필요하다.
그렇다면 참조변수의 타입은 무엇이 되어야 할까?

바로 FunctionalInterface = 함수형 인터페이스 타입이다.

그래서 함수형 인터페이스가 뭘까?

구현 해야 할 추상 메서드가 한 개 있는 인터페이스

예를 들어서 하나의 함수형 인터페이스를 만들어 보겠다.

@FunctionalInterface
public interface MyFunctionalInterface{
	public void run();
}

@FunctionalInterface 애노테이션을 선언하여 해당 인터페이스의 추상메서드가 하나임을 보장받는다. (추상메서드가 1개 이상이면 에러 발생)

MyFunctionalInterface의 추상메서드 이름은 run()이며 매개변수와 리턴타입이 없다.

이제 이 함수형 인터페이스를 사용해보자

public static void main(String[] args){
	MyFunctionalInterface myf = () -> System.out.println("TEST");
    
    myf.run();
}

위 코드를 보면 람다식이 등장하고 해당 람다식이 함수형인터페이스 타입 참조변수 myf에 저장되어 사용되어지는 것을 볼 수 있다.

() -> System.out.println("TEST");

이 람다식의 형태는 함수형인터페이스의 추상메서드 run 의 형태와 닮아있지 않은가?
run은 매개변수와 리턴타입이 없는 추상메서드 이다.
람다식의 괄호 부분이 바로 매개변수를 뜻하며, 화살표 뒤의 내용은 메서드의 구현부이다.

위 람다식은 리턴값이 없고 단순한 출력문을 실행하므로 추상메서드 run과 완벽히 매칭이 된다.

myf.run();

람다식을 담고 있는 참조변수 myf을 활용하여 run을 호출하는 방식으로 사용할 수 있다.

만약 람다식이 없었다면 어떻게 될까?

public class Myfunc implements MyFunctionalInterface{
	@Override
	public void run(){
    	System.out.println("TEST");
    }
}
public static void main(String[] args){
	Myfunc mc = new Myfunc();
    mc.run();
}

이 처럼 MyFunctionalInterface를 오버라이딩하는 클래스를 만들어서 인스턴스를 생성하여 사용해야 했다.

람다식으로 이러한 과정들을 생략하고 바로 인스턴스를 생성할 수 있다.

추가적으로 외부에서 선언된 변수를 람다식 내부에서 변경할 수 없다.
왜냐하면 람다식 내부에서 외부 변수는 final 키워드가 붙어 상수로 취급을 하기 때문이다.


람다식 작성 방법

  1. 매개변수와 리턴값이 없는 경우

    위의 예시과 같다.

  2. 매개변수가 있는 경우

    public interface MyFunctionalInterface{
    	public void sum(int x, int y);
    }

    위와 같은 경우 매개변수가 x, y 두 개를 받아 출력한다고 하면(리턴값 없음)

    (int x, int y) -> System.out.println(x + y)

    람다식으로 이렇게 표현 할 수 있다.

    (x, y) -> System.out.println(x + y)

    추상메서드에 integer로 자료형이 명시되어 있으므로 타입추론이 가능하기 때문에
    람다식에서 자료형을 생략해도 괜찮다.

    x -> System.out.println(x)

    매개변수가 하나일 경우 괄호까지 생략 가능하다.

  3. 매개변수와 리턴값이 있는경우

    public interface MyFunctionalInterface{
    	public int sum(int x, int y);
    }

    위의 추상 메서드는 리턴형이 int이다.

    (int x, int y) -> {return x + y}

    변수 x와 y를 더하여 리턴한다.
    이 때, return문이 한 줄 이라면 return과 중괄호{}를 같이 제거할 수 있다.

    (x, y) -> x + y

    이렇게 간단해진다.


마치며

람다식이 무엇이며 어떻게 작성하는지 알아보았다.
람다식은 익명객체이며 함수형 인터페이스 타입의 참조변수를 필요로 한다.

이 때, 매번 함수형 인터페이스를 만들어서 사용하는건 귀찮은 일이다.
따라서 미리 만들어 놓은 표준 함수형 인터페이스를 사용하는 것을 추천한다.

다음 포스팅에 표준 함수형 인터페이스의 종류와 사용법, 그리고 스트림에 대하여 알아보도록 하겠다.

profile
개발자가 되고싶은

0개의 댓글