목차
자바의 스트림이란 for문과 비슷하게 데이터를 반복적으로 처리하기 위한 기능이다.
스트림의 사전적 정의인 '흐르다', '개울'처럼 자바에서도 데이터를 하나씩 흘려보내며 처리한다는 의미로 스트림이라고 이름 붙어졌다.
하지만 이렇게만 설명하면 도저히 for문과 스트림의 차이점이 무엇인지 애매할 것이다.
for문과 스트림은 둘 다 데이터를 반복적으로 처리하기 위해 사용되지만, 동작 방식과 코드 작성에서 큰 차이를 보인다.
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
for(int n : numbers){
if(n % 2 == 0){
System.out.println(n);
}
}
위의 코드는 배열을 생성하고 그 배열안에서 짝수인것만 골라 출력하는 반복문이다.
이를 스트림으로 재구성하면 아래와 같다.
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
filter안에 있는 람다식은 짝수를 계산하고, forEach는 결과값을 하나씩 반복하여 출력하는 함수이다.
이와 같이 코드가 훨씬 간략화되고 가독성이 좋아진것을 볼 수 있다.
로직이 복잡해질수록 for문의 경우엔 코드가 길어지고 변수 관리가 힘들어진다.
하지만 스트림을 사용한다면 여러 기능과 람다식을 사용하여 코드를 간략화 시킬 수 있다.
스트림은 보통 filter, map등을 사용한 중간연산 forEacah, collect등을 사용한 최종 연산등이 있다.
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 10)
.forEach(System.out::println);
위 코드가 어떻게 동작하는지 알아보자.
위 코드는 양의 정수를 모아놓은 정수형 리스트를 선언하고, numbers.stream()을 통해 리스트를 스트림으로 변환 시킨다.
그리고 filter()를 통해 n이 짝수인 데이터들만 추출하고, map()를 사용하여 짝수인 데이터들은 10을 곱한다.
마지막으로 forEach()를 사용하여 출력하게 된다.
이와 같이 filter는 특정 데이터값을 추출하고 싶을때, map는 데이터를 다른 형태로 변환하고 싶을때 사용한다.
스트림은 보통 람다식과 함께 사용할때 아주 좋은 성능을 보인다.
람다식을 활용한 스트림의 예시를 들자면,
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream()
.filter(n -> n > 3)
.forEach(n -> System.out.println(n));
이와 같이 n이 3보다 큰 숫자를 구하고 싶을때 람다식을 사용하여 n -> n > 3과 같이 표현할 수 있다.
1.filter() - filter괄호 안의 조건에 맞는 값을 추출한다
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
filter를 사용하여 짝수 추출하는 코드
2.map() - 데이터를 다른 형태로 변환한다
numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 10)
.forEach(System.out::println);
3.sorted() - 데이터를 정렬해준다
numbers.stream()
.sorted() //오름차순| 내림차순을 하고싶다면 괄호안에 Comparator.reverseOrder() 추가하기
.forEach(System.out::println);
4.count() - 데이터 개수를 구해준다
long count = numbers.stream()
.count();
5.collect() - 조건 결과를 저장한다
List<Integer> result =
numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList()); //리스트로 변환 toMap()나 toCollection()도 가능
6.Match() -조건 만족 검사
boolean result = numbers.stream()
.anyMatch(n -> n % 2 == 0); //짝수 데이터가 있는지 확인
boolean result2 = numbers.stream()
.allMatch(n -> n % 2 == 0); //보든 값이 짝수인지 확인
스트림은 그 이외에도 앞에서부터 몇개를 가져올지 정해주는 limit(),그 반대로 몇개를 제외할지 정해주는 skip() , 값을 누적해서 계산해주는 reduce()등 다양한 기능을 제공한다.