개발자가 되고 싶은 개발자

[Java] Stream 본문

Dev/Java & Spring

[Java] Stream

Fullth 2021. 10. 5. 16:06

스트림이란?

- 여러 자료에 대한 처리 기능을 미리 구현해 놓은 클래스

 

스트림 연산

- 종류: 중간 연산 / 최종 연산

    - 중간 연산: 자료를 거르거나 변경하여 또 다른 자료를 내부적으로 생성

    - 최종 연산: 중간 연산에서 생성된 내부 자료를 소모하며 연산을 수행

        - 따라서 최종 연산은 마지막에 한 번만 호출됨

        - 최종 연산이 호출되어야만 중간 연산의 결과가 만들어짐

 

자주 사용되는 중간 연산(filter, map)

- filter( ): 조건을 넣고 그 조건에 맞는 참인 경우만 추출하는 경우에 사용

    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
		
        // 3 이상의 값만 출력
        Arrays.stream(array).filter(i -> i >= 3).forEach(i -> System.out.println(i));

    }

- map( ): 스트림 내 요소를 특정 값으로 변경할 때 사용

// 리스트의 요소들을 대문자로 출력하고 싶은 경우    
    public static void main(String[] args) {
        List<String> list = Arrays.asList("banana", "apple", "kiwi");
        
        list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));
    }
// 고객의 나이만 가져오고 싶은 경우
    public static class Customer {
        private int age;

        public int getAge() {
            return age;
        }
    }

    public static void main(String[] args) {
        Customer tomas = new Customer();
        Customer cabin = new Customer();

        tomas.age = 11;
        cabin.age = 22;

        ArrayList<Customer> customerList = new ArrayList<>();
        customerList.add(tomas);
        customerList.add(cabin);

        customerList.stream().map(c-> c.getAge()).forEach(s -> System.out.println(s));
    }

 

자주 사용되는 최종연산(forEach( ), count( ), sum( ), reduce( ))

- 최종 연산은 스트림의 자료를 소모하면서 연산을 수행하기 때문에 최종 연산이 수행되고 나면 해당 스트림은 더 이상 사용할 수 없음.

- 최종 연산은 결과를 만드는데 주로 사용함.

    public static void main(String[] args) {
        int[] array = {1, 3, 5, 7, 9};

        // sum( )
        int sum = Arrays.stream(array).sum();
        System.out.println(sum);

        // count( )
        int count = (int) Arrays.stream(array).count();
        System.out.println(count);

        // 기존의 방식대로 배열의 요소 출력
        for(int i = 0; i < array.length; i++)
            System.out.println(array[i]);

        // 개선된 for문으로 배열의 요소 출력
        for(int i : array)
            System.out.println(i);

        // Stream을 이용한 방식으로 배열의 요소 출력
        Arrays.stream(array).forEach(n -> System.out.println(n));
    }
class mathSum implements BinaryOperator<Integer>, IntBinaryOperator {

    @Override
    public Integer apply(Integer num1, Integer num2) {
        return num1 + num2;
    }

    @Override
    public int applyAsInt(int left, int right) {
        return left + right;
    }
}

public class Main {

    public static void main(String[] args) {
        int[] array = {10, 20};

        int sum = Arrays.stream(array).reduce(new mathSum()).getAsInt();
        System.out.println(sum);
    }
}

스트림의 특징

- 자료의 대상과 관계없이 동일한 연산을 수행한다.

    - 컬렉션의 여러 자료 구조에 대해 작업을 일관성 있게 처리하는 메소드 제공

- 한 번 생성하고 사용한 스트림은 재사용할 수 없다.

- 스트림의 연산은 기존 자료를 변경하지 않는다.

    - 스트림 연산을 위해 사용하는 메모리 공간이 별도로 존재함. 스트림의 메소드를 호출하더라고 기존 자료에 영향 미치지 않음

- 스트림의 연산은 중간 연산과 최종 연산이 있다.

 

Reference

- Do it! 자바 프로그래밍 입문(박은종)