🦁아기사자

[Java] 람다식

코딩하는 하마 2025. 4. 1. 11:50

람다식 사용법

1) 람다함수란?

람다 함수는 익명 함수를 지정하는 용어이다. 즉 이름이 없는 함수로 이는 일급 객체라는 특징을 가지고 있다.

일급 객체란 일반적으로 다들 객체들에 적용 가능한 연산을 모두 지원하느 객체를 가르킨다. 함수를 값으로 사용 할 수도 있으며 파라미터로 전달 및 변수에 대입 하기와 같은 연산들이 가능하다. 

 

2) 람다의 표현식

람다는 매개 변수 화살표 (->) 를 함수 몸체로 이용하여 사용 할 수 있다.

함수 몸체가 단일 실행문이면 괄호를 생략 할 수 있다. 하지만 함수 몸체가 return 문으로만 구성되어 있을 경우 괄호를 생략 할 수 없다. 

 

ex) 

void printVal(String name, int i) {
	System.out.rpintnl(name +"=" + i);
}

 

위 메소드를 아래와 같이 변환할 수 있다.

(name , i) -> System.out.println(name+"="+i)

 

ex2)

int sumArr(int[] arr){
    int sum=0;
    for(int i: arr){
        sum+=i;
    }
    return sum;
}


//람다식으로 변환
(int[] arr) -> {
	int sum=0;
    for(int i: arr) {
    sum+=i;
    }
    return sum;
 }

함수형 인터페이스

1) 함수형 인터페이스란?

함수형 인터페이스는 추상 메소드가 오직 하나인 인터페이스를 의미한다.

추상 메소드가 하나라는 뜻은 default  method 또는 static method 는 여러 개 존재해도 상관 없다는 뜻이다. 

그리고 @FunctionalInterface 어노테이션을 사용하는데, 이 어노테이션은 해당 인터페이스가 함수형 인터페이스 조건에 맞는지 검사해준다. 이는 없어도 괜찮지만 인터페이스 검증과 유지보수를 위해 붙여주는 편이 좋다. 

 

2) 함수형 인터페이스 만들기

@FunctionalInterface
interface CustomInterface<T> {
    // abstract method 오직 하나
    T myCall();
    
    //default method 는 존재해도 상관없음 
    default void printDefault() {
        System.out.println("Hello Default");
    }
    
    //static method 는 존재해도 상관없음 
    static void printStatic() {
        System.out.println("hello static");
    }
}

 

이러한 함수형 인터페이스를 람다식으로 표현할 수 있다. 

아래는 람다식으로 함수형 인터페이스를 표현한 것이다. 

CustomInterface<String> customInterface = () -> "Hello custom";

//abstract method
String s = customInterface.myCall();
System.out.println(s);

//default method
customInterface.printDefault();

//static method
CustomFunctionalInterface.printStatic();

Variable Capture

지역 변수들을 미리 복사해서 가지고 있는 것을 Variable Capture라고 한다.

 

지역 변수를 캡처링하기 위한 2가지 제약 조건 

a. 지역변수는 final 로 선언되어야 한다. 

b. final로 선언되어 있지 않다면 final 처럼 동작해야 한다. 즉 값이 변경될 수 없다. 


메소드, 생성자 레퍼런스

메소드 레퍼런스는 람다식에서 불필요한 매개변수를 제거할 떄 주로 사용한다.  즉 람다식으로 더욱 간단해진 익명 객체를 보다 더 간단하게 사용할 수 있도록 한다. 

 

이는 람다식과 마찬가지로 인터페이스의 익명 구현 객체로 생성된다. 

인터페이스의 추상 메소드가 어떤 매개변수를 가지고 , 반환 타입이 무엇인지에 따라 달라진다. 

 

1) 정적 메소드 레퍼런스 

이를 사용할 경우에는 클래스 이름뒤에 ::기호를 사용하여 정적 메소드 이름을 작성할 수 있다.

클래스 이름 :: 정적 메소드 이름

 

ex)

import java.util.function.IntBinaryOperator;

class Calculator {
    public static int staticMethod(int x, int y){
        return x+y;
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        IntBinaryOperator operator;
        //정적 메소드 참조
        operator = Calculator::staticMethod;
        System.out.println(operator.applyAsInt(5,10));
    }
}

 

 

2) 인스턴스 메소드 레퍼런스 

인스턴스 메소드를 참조할 경우에는 객체를 생성한 뒤 참조 변수 뒤에 ::기호를 사용하여 인스턴스 메소드 이름을 작성할 수 있다. 

참조 변수 :: 인스턴스메소드 이름

 

ex)

class Calculator {
	public in instanceMethod ( int x, int y ) {
    	 return x + y;
    }
}

public class Main{
	public static void main(String[] args) throws Exception {
         IntBinaryOperator operator;
		// 인스턴스 메서드 참조
		Calculator calculator = new Calculator();
		operator = calculator::instanceMethod;
		System.out.println(operator.applyAsInt(5, 10));
	}
}

 

3) 생성자 레퍼런스

메소드 레퍼런스는 생성자 참조도 가능하다. 이는 객체 생성을 의미한다. 

 

[람다식에서 객체를 생성하고 리턴하는 방법]

( a , b) -> { return new 클래스 이름 (a, b);};

 

[생성자 레퍼런스]

클래스 이름 :: new

 

import java.util.function.BiFunction;
import java.util.function.Function;

class Member {
     private String name;
     private String id;

     public Member() {
         System.out.println("매개변수 없는 생성자");
     }

     public Member(String id) {
         System.out.println("id 매개 변수를 갖는 생성자");
         this.id = id;
     }

     public Member(String name , String id){
         System.out.println("두 개의 매개변수를 갖는 생성자");
         this.name = name ;
         this.id = id;
     }

     public String getName() {
         return name;
     }
     public String getId() {
         return id;
     }
}

public class Main {
    public static void main(String[] args) {

        Function<String, Member> function1 = Member::new;
        Member member1 = function1.apply("id");

        BiFunction<String, String, Member> function2 = Member::new;
        Member member2 = function2.apply("id", "name");
    }
}

[참고 자료]

https://yejun-the-developer.tistory.com/12

 

람다식과 외부 변수 참조

모던 Practical 자바 5장 스트림 API를 읽다 흥미로운 코드를 발견했다. (설명을 위해 약간 변형했습니다.) List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); int sum = 0; intList.stream().forEach(n -> sum+=n); System.out.

yejun-the-developer.tistory.com

https://khj93.tistory.com/entry/JAVA-%EB%9E%8C%EB%8B%A4%EC%8B%9DRambda%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95

 

[JAVA] 람다식(Lambda)의 개념 및 사용법

람다함수란? 람다 함수는 프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous functions)를 지칭하는 용어입니다. 현재 사용되고 있는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의 람

khj93.tistory.com

https://hstory0208.tistory.com/entry/Java%EC%9E%90%EB%B0%94-%EB%9E%8C%EB%8B%A4%EC%8B%9DLambda%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95

 

[Java/자바] 람다식(Lambda)이란? 그리고 사용법

람다식이란 ? 람다식이란 쉽게 말해 메서드를 "하나의 식"으로 표현한 것입니다. 하나의 식으로 표현하여 훨씬 간략하게 표현이 가능하게 되며, 메서드의 이름과 반환값이 없어지므로 "익명함수

hstory0208.tistory.com

https://bcp0109.tistory.com/313

 

Java 8 함수형 인터페이스 (Functional Interface)

Overview 함수형 인터페이스란 1 개의 추상 메소드를 갖는 인터페이스를 말합니다. Java8 부터 인터페이스는 기본 구현체를 포함한 디폴트 메서드 (default method) 를 포함할 수 있습니다. 여러 개의 디

bcp0109.tistory.com

https://ittrue.tistory.com/162

 

[Java] 자바 메서드 레퍼런스(Method Reference) 개념 정리 및 활용

메서드 레퍼런스란? (메서드 참조 : Method Reference) 메서드 레퍼런스는 람다식에서 불필요한 매개변수를 제거할 때 주로 사용한다. 즉, 람다식으로 더욱 간단해진 익명 객체를 보다 더 간단하게 사

ittrue.tistory.com