자바 - 람다 표현식

안녕하세요, 미래의 자바 마법사 여러분! 오늘 우리는 람다 표현식의 세계로 흥미로운 여정을 떠납니다. 프로그래밍 초보자라고 걱정하지 마세요 - 저는 이 개념을 단계별로 안내해 드릴 것입니다. 수년 동안 수많은 학생들을 가르친 경험을 바탕으로 말이죠. 그러니 커피 한 잔 (또는 차, 그게 당신의 취향이라면)을 마시면서, 이제 시작해 보겠습니다!

Java - Lambda Expressions

람다 표현식이란?

상상해 보세요. 파티에서 친구들에게 장난을 하고 싶어요. 전체 장난을 적어서 종이를 돌려가며 전달하는 것보다 그냥 소리로 말하는 것이 더 쉬운 건 아닐까요? 자바에서 람다 표현식이 하는 일은 바로 그거입니다 - 단방법 인터페이스(기능 인터페이스)의 인스턴스를 표현하는 빠르고 간결한 방법을 제공합니다.

람다 표현식은 자바 8에서 도입되어 기능적 프로그래밍의 이점을 자바에 가져오기 위해 만들어졌습니다. 이는 코드를 더 읽기 쉽게, 간결하게, 때로는 더 효율적으로 만듭니다.

람다 표현식 문법

람다 표현식의 기본 문법은 다음과 같습니다:

(parameters) -> { body }

이는 이름 없는 작은 함수입니다. 이를 간단히 설명해 보겠습니다:

  • parameters: 입력 매개변수(있을 경우)
  • ->: 매개변수와 본문을 구분하는 화살표 토큰
  • body: 실행할 코드를 포함

자바 람다 표현식의 특성

  1. 타입 추론: 자바는 종종 매개변수의 타입을 추론할 수 있기 때문에, 항상 지정할 필요는 없습니다.
  2. 단일 표현식: 본문이 단일 표현식만 포함하는 경우, 대괄호를 생략할 수 있습니다.
  3. 여러 매개변수: 매개변수는 0개, 1개, 또는 여러 개일 수 있습니다.
  4. 반환 문구: 본문이 단일 표현식인 경우, 반환 문구는 선택 사항입니다.

자바 람다 표현식 예제

람다 표현식이 실제 어떻게 작동하는지 예제를 통해 살펴보겠습니다.

예제 1: 간단한 람다 표현식

// 전통적인 방법
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};

// 람다 방법
Runnable lambdaRunnable = () -> System.out.println("Hello, Lambda World!");

// 둘 다 실행
runnable.run();
lambdaRunnable.run();

이 예제에서 우리는 Runnable 객체를 생성하고 있습니다. 전통적인 방법은 익명 내부 클래스를 생성하는 반면, 람다 방법은 더 간결합니다. 둘 다 실행 시 메시지를 출력합니다.

예제 2: 매개변수 있는 람다 표현식

interface MathOperation {
int operate(int a, int b);
}

public class LambdaExample {
public static void main(String[] args) {
MathOperation addition = (a, b) -> a + b;
MathOperation subtraction = (a, b) -> a - b;

System.out.println("10 + 5 = " + addition.operate(10, 5));
System.out.println("10 - 5 = " + subtraction.operate(10, 5));
}
}

여기서 우리는 기능 인터페이스 MathOperation을 정의하고 람다 표현식을 사용하여 덧셈과 뺄셈 연산을 구현합니다. 코드가 얼마나 깨끗하고 가독성이 높아졌는지 확인해 보세요!

자바 람다 표현식의 범위

람다 표현식은 내부 클래스와 같은 범위를 가집니다. 그들은 둘러싸인 범위에서 변수를 캡처할 수 있지만, 이러한 변수는 효과적으로 최종적이어야 합니다(초기화된 후 값이 변경되지 않음).

public class ScopeExample {
public static void main(String[] args) {
int multiplier = 2;
IntUnaryOperator doubler = (n) -> n * multiplier;
System.out.println(doubler.applyAsInt(4)); // 출력: 8

// 이렇게 하면 오류가 발생합니다:
// multiplier = 3;
}
}

이 예제에서 multiplier는 효과적으로 최종적이며 람다 표현식에서 사용됩니다.

람다 표현식에서 상수 사용

상수는 람다 표현식에서 자유롭게 사용할 수 있습니다. 그들은 람다 표현식을 더 유연하고 재사용 가능하게 만드는 좋은 방법입니다.

public class ConstantExample {
private static final int MAGIC_NUMBER = 42;

public static void main(String[] args) {
IntSupplier magicSupplier = () -> MAGIC_NUMBER;
System.out.println("마법의 숫자는: " + magicSupplier.getAsInt());
}
}

여기서 우리는 상수 MAGIC_NUMBER를 람다 표현식에서 사용하고 있습니다. 이는 스코프 규칙을 위반하지 않습니다.

람다 표현식을 컬렉션에서 사용

람다 표현식은 컬렉션과 함께 사용할 때 진정한 매력을 발휘합니다. 코드를 더 가독성 있고 간결하게 만들 수 있습니다. 몇 가지 예제를 살펴보겠습니다:

리스트 정렬

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// 전통적인 방법
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});

// 람다 방법
names.sort((a, b) -> b.compareTo(a));

System.out.println(names); // 출력: [David, Charlie, Bob, Alice]

리스트 반복

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 전통적인 방법
for (Integer number : numbers) {
System.out.println(number);
}

// 람다 방법
numbers.forEach(number -> System.out.println(number));

// 더 간결하게
numbers.forEach(System.out::println);

리스트 필터링

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 짝수를 가져오기
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());

System.out.println(evenNumbers); // 출력: [2, 4, 6, 8, 10]

마지막 예제에서 우리는 스트림 API와 람다 표현식을 사용하여 리스트에서 짝수를 필터링합니다. filter 메서드는 Predicate를 받아들이며, 이를 람다 표현식으로 제공합니다.

결론

그렇습니다, 여러분! 우리는 람다 표현식의 땅을 여행했습니다. 그들의 기본 문법에서 컬렉션에서의 실질적인 응용까지. 람다 표현식은 요리의 향신료처럼, 적절히 사용하면 코드를 더 읽기 쉽고 효율적으로 만들 수 있습니다!

새로운 개념을 습득하는 것은 연습이 관键입니다. 그러니 코드를 람다로 변환해 보세요! 그리고 기억하세요, 오류를 만나는 것은 학습의 기회입니다. 항상 학생들에게 말하는 것처럼, 프로그래밍에서 오류는 성장의 가면입니다.

계속 코딩하고, 학습하고, 가장 중요한 것은, 즐기세요! 다음 시간까지, 여러분의 친절한 이웃 자바 교사가 인사드립니다. 즐겁게 코딩하세요!

Credits: Image by storyset