람다를 공부하기에 앞서서 익명 클래스에 대해 알아보아야 합니다.
익명 클래스는 말 그대로 이름이 없는 클래스를 의미합니다.
보통 한 번만 사용할 일회성 클래스를 만들 때, 별도의 파일 없이 코드 안에서 바로 정의하여 사용할 수 있습니다.
주로 인터페이스나 추상 클래스를 구현할 때 사용합니다.
여기서 람다(lambda)라는 것은, 익명 클래스를 더 간결하게 표현한 문법입니다.
public interface Calculator {
int sum(int a, int b);
}
public class Main {
public static void main(String[] args) {
// 익명 클래스로 Calculator를 구현
// 별도의 클래스 이름 없이 바로 구현하여 변수에 할당
Calculator calculator = new Calculator() {
@Override
public int sum(int a, int b) {
return a + b;
}
};
int result = calculator.sum(1, 2);
System.out.println(result); // 3
}
}
람다는 익명 클래스를 더 간결하게 표현한 문법이라고 하였습니다. 람다는 함수형 인터페이스에서만 사용할 수 있습니다.
@FunctionalInterface
public interface Calculator {
int sum(int a, int b);
}
public class Main {
public static void main(String[] args) {
// 람다로 Calculator를 구현
Calculator calculator = (a, b) -> a + b;
int result = calculator.sum(1, 2);
System.out.println(result); // 3
}
}
함수형 인터페이스란?
추상 메서드가 1개인 인터페이스를 의미합니다.
public class Main {
public static int calculate(int a, int b, Calculator calc) {
return calc.sum(a, b);
}
public static void main(String[] args) {
int result;
// 1. 익명 클래스를 이용한 전달
Calculator cal1 = new Calculator() {
@Override
public int sum(int a, int b) {
return a + b;
}
};
result = calculate(1, 2, cal);
// 2. 람다식을 이용한 전달
Calculator cal2 = (a, b) -> a + b;
result = calculate(1, 2, cal);
// 3. 람다식을 직접 전달
result = calculate(1, 2, (a, b) -> a + b);
스트림은 Java 버전 8부터 도입된 데이터 처리 도구입니다. 컬렉션이나 배열에 저장된 데이터를 효율적으로 선언할 수 있는 데이터의 흐름을 의미합니다.
즉, 데이터를 반복문 없이 한 줄로 가공, 필터링, 변환, 집계 등 다양한 작업을 할 수 있게 해줍니다.
컬렉션, 배열 등에서 스트림을 생성합니다.
List<Integer> list = Arrays.asList(1, 2, 3);
Stream<Integer> stream = list.stream();
map(), filter(), sorted() 등의 메서드를 활용합니다. 해당 메서드들의 연산 결과 또한 스트림이기 때문에 여러 번 반복해서 사용할 수도 있습니다.
stream.filter(n -> n % 2 == 0) // 짝수인 요소
.map(n -> n * 10) // 각 요소에 10을 곱함
collect(), forEach(), count(), redue() 등의 메서드를 활용합니다. 중간 연산 단계의 메서드들과는 다르게 연산 결과가 스트림이 아니기 때문에 한 번만 사용할 수 있습니다.
// collect
.collect(Collectors.toList());
// forEach
.forEach(System.out::println);
::는 무슨 의미인가요?
::는 메서드 참조(Method Reference) 연산자입니다.
Java 버전 8부터 도입된 문법으로, 람다식에서 기존 메서드만 호출할 때 더욱 간결하게 표현할 수 있도록 해줍니다.위 System.out::println을 예시로 들어보면,
원래는 람다식으로list.forEach(n -> System.out.println(n));이렇게 작성해야하는 구문을
list.forEach(System.out::println);이렇게 작성하는 것입니다.
즉, System.out의 println 메서드를 참조하여 람다식에서 받은 값을 그대로 전달해 호출하라는 의미를 지니고 있습니다.
사용형태
- 정적 메서드 참조: className::methodName
e.g. Math::abs- 인스턴스 메서드 참조: variableName::methodName
e.g. System.out::println- 생성자 참조: className::new
e.g. ArrayList::new람다식이 단순히 기존 메서드 하나만 호출할 때, 불필요한 매개변수 선언 없이 코드를 더 간결하게 만들고 싶을 때 해당 연산자를 사용합니다.
자료 및 코드 출처: 스파르타 코딩클럽