- 함수형 프로그래밍에서 사용되는 함수를 간결하게 표현하기 위한 방법 중 하나이다.
익명 함수(anonymous function)
의 한 형태로써, 메서드에 대한 구현을 간결하게 표현하는 방법이다.- 람다식은 함수형 인터페이스(Functional Interface)와 함께 사용되며,
java.util.function 패키지에는 많은 함수형 인터페이스가 정의되어 있다.
(parameter) -> {expression}
parameter
: 메서드에서 사용할 매개변수
expression
: 메서드의 구현체
// 간단 예시)
(int x, int y) -> {return x+y;}
public class LambdaExample {
public static void main(String[] args) {
// (int x, int y) -> {return x+y;} : 람다식을 사용하여 add 메서드 구현
MathOperation add = (x,y) -> x+y;
// MathOperation add = (int x, int y) -> {return x+y;};
// add 메서드를 사용하여 10과 20 더하기
int result = add.operation(10,20);
System.out.println(result);
}
}
@FunctionalInterface // 함수형 인터페이스
public interface MathOperation {
public int operation(int x, int y); // 추상 메서드
}
public class LambdaApply {
public static void main(String[] args) {
StringOperation toUpperCase = (s) -> s.toUpperCase();
StringOperation toLowerCase = (s) -> s.toLowerCase();
String input = "Lambda Expressions";
System.out.println(input);
System.out.println(processString(input, toUpperCase));
System.out.println(processString(input, toLowerCase));
}
public static String processString(String input, StringOperation operation) {
return operation.apply(input);
}
}
public interface StringOperation {
String apply(String s);
}
- 배열을 스트림으로 변환한다는 것은 배열의 원소들을 스트림 형태로 변환하여 처리할 수 있게 하는 것이다.
- 스트림은 원본 데이터를 변경하지 않고, 필요한 데이터 처리 작업을 적용한 결과를 생성하기 때문에 인덱스를 통한 직접 접근은 제공하지 않는다.
1) 스트림(Stream)은 데이터 흐름을 다루기 위한 선언형 API이다.
2) 스트림을 사용하여 필터링, 매핑, 정렬 등 다양한 데이터 처리 작업을 적용할 수 있으며, 최종 결과를배열
이나컬렉션
으로변환
할 수 있다.
3) 스트림은 데이터 처리 작업을 연속적인 파이프라인으로 나타낼 수 있어 가독성이 높고, 병렬 처리를 쉽게 구현할 수 있다.
구분 | 설명 | 예시 메서드 |
---|---|---|
중간연산 | 스트림의 원소를 변환, 필터링, 정렬 등 중간 단계에서 처리하는 연산 | filter(), map(), sorted(), distinct(), limit(), skip() 등 |
최종연산 | 스트림의 최종결과를 반환하는 연산 | forEach(), count(), collect(), reduce(), min(), max() 등 |
스트림 생성 | 컬렉션, 배열, 파일 등의 데이터 소스를 스트림으로 변환 | stream(), parallelStream() |
스트림 종료 | 스트림의 자원을 해제하고 최종결과를 반환 | close(), toArray() 등 |
병렬 스트림 | 여러 개의 스레드를 이용하여 동시에 처리하는 스트림 | parallel(), sequential() |
스트림 연결 | 두 개 이상의 스트림을 연결하여 처리하는 스트림 | flatMap(), concat() 등 |
스트림 요약 | 스트림의 요약 정보를 반환하는 연산 | summaryStatistics(), averagingDouble(), summingInt() 등 |
스트림 요소검색 | 스트림에서 특정 요소를 검색하거나 확인하는 연산 | anyMatch(), allMatch(), noneMatch(), findFirst(), findAny(), forEachOrdered() 등 |
스트림 합치기 | 두 개 이상의 스트림을 합쳐서 처리하는 연산 | reduce(), collect() 등 |
// 간단 예시
import java.util.Arrays;
public class StreamAPITest {
public static void main(String[] args) {
int[] numbers = {1,2,3,4,5};
// 기존 방식
// int even = 0;
// for (int num : numbers) {
// if (num % 2 == 0) {
// even+=num;
// }
// }
// Stream, 람다식 활용
int sumOfEvens = Arrays.stream(numbers)
.filter(n -> n % 2 == 0) // 람다식
.sum();
System.out.println("sumOfEvens = " + sumOfEvens); // 6
int[] evenNumbers = Arrays.stream(numbers)
.filter(n -> n % 2 == 0) // 람다식
.toArray();
for (int even : evenNumbers) {
System.out.println("even = "+ even);
}
}
}
✓ List에 저장된 정수들의 짝수여부를 확인하여 짝수만 정렬하고 제곱한 합을 계산한다.
1) numbers 리스트를 스트림으로 변환한다.
2)
filter()
메서드를 사용하여 짝수만 필터링 한다.
(여기서 함수형 인터페이스인Predicate
를 사용한다.)3)
sorted()
메서드를 사용하여 정렬한다.4)
map()
메서드를 사용하여 각 숫자를 제곱한다.
(*주어진 함수를 스트림의 모든 원소에 적용한 결과로 새로운 스트림을 생성)5)
reduce()
메서드를 사용하여 합계를 계산한다.
(*스트림의 요소를 결합하여 하나의 결과 값을 생성)6) 출력
✅ 해당 예제는 함수형 인터페이스
Predicate<T>
를 사용하여
짝수 여부를 판별하는 람다 표현식을 정의하고,(\*booolean test(T t));
Stream API
를 사용하여 여러 작업을 연속적으로 수행한다..
이렇게 하면 간결하고도 가독성이 높은 코드를 작성할 수 있다.
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
// 자바에서 제공된 함수형 인터페이스를 사용한 짝수 여부 판별
Predicate<Integer> isEven = n -> n % 2 == 0;
// Stream API를 사용해 짝수만 필터링, 정렬, 제곱하고 합계를 계산
int sumOfSquares = numbers.stream()
.filter(isEven)
.sorted()
.map(n -> n*n)
.reduce(0, Integer::sum);
System.out.println(sumOfSquares); // 220
}
}
✓ 정수 list에서 각 원소를 제곱한 값을 출력한다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExamples {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 스트림의 각 원소를 제곱한 값으로 구성된 새로운 리스트 생성
List<Integer> squaredNumbers = numbers.stream()
.map(n -> n*n)
.collect(Collectors.toList());
System.out.println(squaredNumbers); // [1, 4, 9, 16, 25]
}
}
✓ Stream의 문자열 원소를 대문자로 변환한다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExamples2 {
public static void main(String[] args) {
List<String> worlds = Arrays.asList("apple", "banana", "charry", "orange");
// 스트림의 각 원소를 대문자로 변환한 새로운 리스트 생성
List<String> upperCaseWorlds = worlds.stream()
.map(word -> word.toUpperCase())
.collect(Collectors.toList());
System.out.println(upperCaseWorlds); // [APPLE, BANANA, CHARRY, ORANGE]
}
}