본문 바로가기

p-languages/java

java/ Stream 중간 처리 메서드 - filtering, mapping, sorting, looping

중간 처리 메서드 - 필터링filtering, 매핑mapping, 정렬sorting, 루핑looping

** 중간 처리 메서드의 리턴 타입은 모두 Stream이다 


1. 필터링

distinct()

중복을 제거한다

filter()

람다식 실행문이 true가 되는 값을 filter한다

 

e.g.

import java.util.*;

public class FilteringExample {
    public static void main(String[] args) {
        List<String> colors = Arrays.asList("red", "green", "blue", "orange", "red");

        colors.stream()
                //중복 제거
                .distinct()
                //"e"로 끝나는 요소 필터
                .filter(c -> c.endsWith("e"))
                //출력
                .forEach(c -> System.out.println(c));
    }
}
출력

blue
orange

2. 매핑

flatMap()

요소를 대체하는 복수 개의 요소들로 구성된 새로운 스트림을 리턴

import java.util.*;

public class FlatMapExample {
    public static void main(String[] args) {
        List<String> input1 = Arrays.asList("중간 처리 메서드", "flatMap() 예시");
        input1.stream()
                //flatMap()을 사용해 " "단위로 split해 반환
                .flatMap(data -> Arrays.stream(data.split(" ")))
                .forEach(word -> System.out.println(word));

        System.out.println();

        List<String> input2 = Arrays.asList("1, 2, 3", "10, 9, 8");
        input2.stream()
                //flatMapToInt()를 사용해 
                .flatMapToInt(data -> {
                    //","단위로 나누어 String 배열에 저장
                    String[] strArr = data.split(",");
                    //int 배열 생성
                    int[] intArr = new int[strArr.length];
                    //String 배열 값은 int 배열에 넣어줌 (trim()으로 공백 제거)
                    for(int i=0; i<intArr.length; i++){
                        intArr[i] = Integer.parseInt(strArr[i].trim());
                    }
                    //int 배열을 stream으로 반환
                    return Arrays.stream(intArr);
                })
                //stream의 요소를 출력
                .forEach(num -> System.out.println(num));
    }
}
출력

중간
처리
메서드
flatMap()
예시

1
2
3
10
9
8

flatMapTo(Double/Int/Long/Obj) 의 형태로 사용

 

map()

요소를 대체하는 새로운 요소로 구성된 새로운 스트림을 리턴

import java.util.*;

public class MapExample {
    public static void main(String[] args) {
        List<Student> studentList = Arrays.asList(
                new Student("jane", 20),
                new Student("john", 12),
                new Student("kim", 30)
        );

        studentList.stream()
                .mapToInt(Student :: getScore)
                .forEach(score -> System.out.println(score));
    }
}
출력

20
12
30

mapTo(Double/Int/Long/Obj)의 형태로 사용

 

asDoubleStream()

IntStream의 int 요소나 LongStream의 long 요소를 double로 타입 변환해 DoubleStream을 생성

asLongStream()

IntStream의 int 요소를 long 요소로 타입 변환해 LongStream을 생성

boxed()

int, long, double 요소를 Integer, Long, Double 요소로 박싱해 Stream을 생성

import java.util.Arrays;
import java.util.stream.IntStream;

public class AsStreamAndBoxedEx {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};

        IntStream stream = Arrays.stream(arr);
        stream
                .asDoubleStream() //DoubleStream
                .forEach(d -> System.out.println(d));

        System.out.println();

        stream = Arrays.stream(arr);
        stream
                .boxed() //Stream<Integer>
                .forEach(obj -> System.out.println(obj.intValue()));
    }
}

3. 정렬

요소가 최종 처리 되기 전 중간 처리 단계에서 요소를 정렬해 최종 처리 순서를 변경

sorted()

*객체 요소일 경우 클래스가 Comparable을 구현해 사용하거나/구현하지 않고 Comparator.comparing() 메서드를 사용한다

> 보충) comparable, comparator, reverseOrder

import java.util.*;
import java.util.stream.IntStream;

public class SortingExample {
    public static void main(String[] args) {
        IntStream intStream = Arrays.stream(new int[] {2, 5, 7, 22, 1});
        intStream
                .sorted()
                .forEach(n -> System.out.println(n));

        System.out.println();
        
        List<Student> studentList = Arrays.asList(
                new Student("jane", 90),
                new Student("yang", 67),
                new Student("derek", 75)
        );
        studentList.stream()
                .sorted(Comparator.comparing(Student::getScore))
                .forEach(s -> System.out.println(s.getScore()));

    }
}
출력

1
2
5
7
22

67
75
90

 

4. 루핑 Looping

peek() 중간 처리 메서드

중간 처리 단계에서 전체 요소를 루핑하면서 추가적인 작업을 하기 위해 사용

최종 처리 메서드가 실행되지 않으면 지연 → 최종 처리 메서드 호출 뒤 동작

forEach() 최종 처리 메서드

파이프라인 마지막에서 루핑하면서 요소를 하나씩 처리

요소를 소비하는 최종 처리 메서드 →  forEach() 호출 이후 다른 최종 처리 메서드를 사용할 수 없다

 

→ 기능면에서 동일하지만 동작 방식에서 다르다. (중간/최종) 주로 연산 중간에 결과를 확인해 디버깅하고자 할 때 peek() 메서드를 사용한다.

 

e.g.

import java.util.Arrays;

public class LoopingExample {
    public static void main(String[] args) {
        int[] arr = {10, 20, 25, 30, 35};

        System.out.println("peek()를 마지막에 호출");
        Arrays.stream(arr)
                .filter(a -> a%2 ==0)
                .peek(n -> System.out.println(n));

        System.out.println("peek() 호출 후 최종 처리 메서드 sum() 호출");
        int sum = Arrays.stream(arr)
                .filter(a -> a%2==0)
                .peek(n -> System.out.println(n))
                .sum();
        System.out.println("sum=" + sum);

        System.out.println("forEach()를 마지막에 호출");
        Arrays.stream(arr)
                .filter(a -> a%2==0)
                .forEach(n -> System.out.println(n));
    }
}
출력

peek()를 마지막에 호출 //peek()는 지연되어 동작X
peek() 호출 후 최종 처리 메서드 sum() 호출 //peek() 동작
10
20
30
sum=60
forEach()를 마지막에 호출
10
20
30

reference.

신용권, 이것이 자바다, 한빛미디어, 2018

 

Stream (Java Platform SE 8 )

A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())

docs.oracle.com