Java Lambda
자바 람다 표현식 (Java Lambda Expressions): 개념 및 사용법
- *람다 표현식(Lambda Expressions)**은 자바 8부터 도입된 기능으로, **익명 함수(Anonymous Function)**를 구현하는 간결한 방법입니다. 즉, 코드 내에서 이름이 없는 함수를 작성하는 방식입니다. 람다 표현식을 사용하면 코드가 간결해지고, 함수형 프로그래밍 스타일을 적용할 수 있습니다.
람다 표현식은 주로 함수형 인터페이스와 함께 사용되며, 코드의 간결성과 가독성을 크게 높여줍니다.
1. 람다 표현식의 기본 구조
람다 표현식은 다음과 같은 형태를 가집니다:
(매개변수) -> { 함수의 본문 }
- 매개변수: 람다 표현식이 입력받을 매개변수(0개 이상).
- 화살표
>
: 람다의 매개변수와 함수 본문을 구분하는 역할. - 함수의 본문: 람다 표현식이 수행할 작업. 여러 줄일 경우 중괄호
{}
로 묶습니다.
람다 표현식의 예시
// 예: 두 숫자의 합을 구하는 람다 표현식
(int a, int b) -> { return a + b; }
- 위 람다는
a
와b
를 매개변수로 받아, 두 숫자를 더한 값을 반환합니다.
2. 함수형 인터페이스
- *함수형 인터페이스(Functional Interface)**는 추상 메서드가 하나만 정의된 인터페이스를 의미합니다. 자바에서 람다 표현식은 함수형 인터페이스의 구현체로
사용됩니다. 자바에서 미리 정의된 함수형 인터페이스는 주로
.util.function
패키지에 포함되어 있습니다.
대표적인 함수형 인터페이스
Function<T, R>
: 입력값T
를 받아서 결과값R
을 반환하는 함수.Consumer<T>
: 입력값T
를 받아서 어떤 동작을 수행하고 결과를 반환하지 않는 함수.Supplier<T>
: 입력값 없이 결과값T
를 반환하는 함수.Predicate<T>
: 입력값T
를 받아서true
또는false
를 반환하는 함수.
함수형 인터페이스 정의
사용자 정의 함수형 인터페이스는 @FunctionalInterface
애노테이션을 사용할 수 있습니다. 이 애노테이션은 함수형 인터페이스임을 명시하고, 하나의 추상 메서드만 가질 수 있다는 것을 보장합니다.
@FunctionalInterface
interface MyFunctionalInterface {
void doSomething();
}
3. 람다 표현식 사용 예시
3.1 Runnable
인터페이스와 람다
Runnable
인터페이스는 매개변수가 없고 반환값도 없는 run()
메서드를 포함하고 있으며, 이를 람다로 구현할 수
있습니다.
public class Main {
public static void main(String[] args) {
// 기존 익명 클래스 방식
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("기존 방식의 스레드 실행");
}
};
// 람다 표현식 방식
Runnable runnable2 = () -> System.out.println("람다 방식의 스레드 실행");
// 스레드 실행
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
출력 예시:
기존 방식의 스레드 실행
람다 방식의 스레드 실행
3.2 Comparator
와 람다
Comparator
인터페이스는 두 객체를 비교하는 compare()
메서드를 포함하고 있으며, 이를 람다로 간결하게
구현할 수 있습니다.
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
String[] fruits = {"Banana", "Apple", "Orange"};
// 기존 익명 클래스 방식
Arrays.sort(fruits, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2); // 알파벳 순으로 정렬
}
});
System.out.println(Arrays.toString(fruits));
// 람다 표현식 방식
Arrays.sort(fruits, (s1, s2) -> s1.compareTo(s2));
System.out.println(Arrays.toString(fruits));
}
}
출력 예시:
[Apple, Banana, Orange]
[Apple, Banana, Orange]
3.3 Function
인터페이스와 람다
Function<T, R>
인터페이스는 하나의 입력을 받아서 변환한 결과를 반환하는 함수를 정의하는 데 사용됩니다. 예를 들어,
입력된 문자열의 길이를 반환하는 람다 표현식을 사용할 수 있습니다.
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// 문자열의 길이를 반환하는 람다 표현식
Function<String, Integer> stringLength = s -> s.length();
System.out.println(stringLength.apply("Hello")); // 출력: 5
System.out.println(stringLength.apply("Lambda")); // 출력: 6
}
}
3.4 Consumer
인터페이스와 람다
Consumer<T>
인터페이스는 입력을 받아서 어떤 동작을 수행하고, 반환값이 없는 함수형 인터페이스입니다.
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// 문자열을 출력하는 람다 표현식
Consumer<String> printMessage = message -> System.out.println(message);
printMessage.accept("Hello, world!"); // 출력: Hello, world!
}
}
3.5 Predicate
인터페이스와 람다
- *
Predicate<T>
*는 입력값에 대해true
또는false
를 반환하는 함수형 인터페이스입니다.
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
// 문자열이 빈 문자열인지 확인하는 람다 표현식
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // 출력: true
System.out.println(isEmpty.test("Lambda")); // 출력: false
}
}
4. 메서드 참조(Method Reference)
람다 표현식은 메서드 참조로 더욱 간결하게 표현할 수 있습니다. 메서드 참조는 이미 존재하는 메서드를 람다 표현식 대신 사용할 수 있도록 하는 기능입니다.
메서드 참조 유형
- 정적 메서드 참조:
ClassName::methodName
- 인스턴스 메서드 참조:
instance::methodName
- 생성자 참조:
ClassName::new
메서드 참조 예제
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] fruits = {"Banana", "Apple", "Orange"};
// 메서드 참조를 사용한 정렬 (정적 메서드 참조)
Arrays.sort(fruits, String::compareToIgnoreCase);
System.out.println(Arrays.toString(fruits)); // 출력: [Apple, Banana, Orange]
}
}
5. 스트림과 람다 표현식
람다 표현식은 자바 8에서 도입된 스트림(Stream) API와 자주 함께 사용됩니다. 스트림은 컬렉션 데이터를 처리하는 데 있어 선언적이고 함수형 프로그래밍 스타일을 제공합니다.
스트림과 람다 예제
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange");
// 스트림과 람다를 사용하여 대문자로 변환 후 출력
fruits.stream()
.map(String::toUpperCase) // 모든 문자열을 대문자로 변환
.forEach(System.out::println); // 각 요소를 출력
}
}
출력 예시:
APPLE
BANANA
ORANGE
6. 요약
- 람다 표현식은 자바에서 익명 함수를 간결하게 표현하는 방식으로, 함수형 인터페이스를 구현하는데 사용됩니다.
- 함수형 인터페이스는 하나의 추상 메서드를 가지며, 대표적인 인터페이스로는
Function
,Consumer
,Predicate
등이 있습니다. - 람다 표현식은 자바 8 이후 도입된 스트림 API와 함께 자주 사용되며, 코드를 더욱 간결하고 가독성 있게 작성할 수 있습니다.
- 메서드 참조는 람다 표현식을 더 간결하게 사용할 수 있는 기능으로, 이미 존재하는 메서드를 참조하는 방식입니다.
람다 표현식은 자바에서 함수형 프로그래밍 스타일을 제공하며, 코드의 가독성과 효율성을 높여주는 중요한 기능입니다.