Java 함수형 인터페이스(3) - Stream API

강서진·2023년 11월 19일
0

Java

목록 보기
25/35
post-custom-banner

강좌 Course 2. Part 2. ch3 5, 6강 요약

스트림

스트림은 자바8에서 도입된 기능으로, 데이터의 흐름을 다루기 위한 선언형 api이다. 필터링, 매핑, 정렬 등 다양한 데이터 처리 작업을 할 수 있으며, 최종 결과를 배열이나 컬렉션으로 변환해준다. 데이터처리 작업을 연속적인 파이프라인으로 나타낼 수 있어 가독성이 높고, 병렬 처리가 쉽다.

배열은 스트림으로 변환할 수 있다. 배열을 스트림으로 변환한다는 것은 배열의 원소들을 스트림 형태로 변환하여 처리하는 것이다. 원본 데이터를 변경하지 않고, 필요한 데이터 처리 작업을 적용한 결과를 생성하기 때문에 인덱스를 통한 직접 접근을 제공하지 않는다.

연속적인 파이프라인은 여러 메서드를 한 줄에 적용할 수 있다는 뜻이다. 배열을 스트림으로 변환할 때는 Arrays.stream() 메서드를 사용한다.

예전에는 1부터 5의 정수 배열에서 짝수의 합을 구하기 위해서는 for문과 if문을 작성해야 했지만, 스트림을 사용하면

int[] numbers = {1,2,3,4,5};
int sumOfEvens = Array.stream(numbers).
					   filter(n -> n%2==0). // 람다식으로 작성
                       sum();

이렇게 간결한 한 줄로 구할 수 있다.
* 편의상 메서드마다 줄바꿈을 넣었다.

스트림을 배열로 변환하려면 toArray() 메서드를 사용하고, 컬렉션으로 변환하려면 collect() 메서드를 사용한다.

스트림에는 두 가지 연산이 있는데, 하나는 중간연산으로, 스트림을 처리하고 다른 스트림을 반환한다. 다른 하나는 최종연산으로, 스트림을 처리한 최종 결과를 반환한다.
중간연산은 filter(), map(), sorted() 등이 대표적이며, 최종연산은 forEach(), count(), collect() 등이 있다.

스트림 활용 메서드

스트림 api와 함수형 인터페이스를 사용하여 list에 저장된 정수의 짝수 여부를 판별하고, 짝수만 필터링하여 정렬하고, 각 숫자를 제곱한 후 모든 숫자의 합을 계산할 수 있다.

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;

        // 짝수 필터링, 정렬, 제곱, 합
        int sumOfSquares = numbers.stream()
                .filter(isEven) // 주어진 조건에 맞게 필터링 (그냥 n->n%2==0를 넣어도 됨)
                .sorted() // 정렬
                .map(n->n*n) // 주어진 함수를 스트림의 모든 원소에 적용한 결과로 새로운 스트림 생성
                .reduce(0, Integer::sum); // 스트림의 요소를 결합하여 하나의 결과값을 생성, (초기값, 함수)

        System.out.println(sumOfSquares); // 220
    }
}

또는 같은 파일 안에 isEven이라는 함수를 정의하여 filter에 메서드를 참조할 수도 있다.

정수 리스트에서 map을 사용하여 각 원소를 제곱하고 collect로 새 리스트를 만들어 반환할 수도 있다.

public class MapExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1,2,3,4,5);

        List<Integer> sqNum = numbers.stream()
                .map(n->n*n) // 새로운 스트림
                .collect(Collectors.toList()); // List로 스트림 변환

        System.out.println(sqNum);
    }
}

정수뿐만 아니라 문자열도 map을 사용할 수 있다.

public class MapExample2 {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple","banana","cherry","orange");

        List<String> upperCaseWords = words.stream()
                .map(word->word.toUpperCase()) // 새로운 스트림
                .collect(Collectors.toList()); // List로 스트림 변환

        System.out.println(upperCaseWords);
    }
}
post-custom-banner

0개의 댓글