-
스트림 활용Java/모던자바인액션요약 2022. 8. 18. 00:01728x90
필터링
filter 메서드
스트림 인터페이스는 filter 메서드를 지원합니다.
filter 메서드는 프레디케이트를 인수로 받아 프레디케이트와 일치하는 모든 요소를 포함하는 스트림을 반환합니다.(중간 연산)
List<Dish> vegetarianMenu = menu.stream() .filter(Dish::isVegetarian) .collect(toList());
distinct 메서드
중복을 필터링합니다.
List<Integer> numbers = Arrays.asList(1, 2, 3, 1, 2, 3, 4, 5, 6); numbers.stream() .filter(i -> i % 2 == 0) .distinct() .forEach(System.out::println);
프레디케이트를 이용한 슬라이싱
takeWhile 활용
320칼로리 이하의 요리를 선택하기 위한 방법?
위에 사용했던 필터 메서드를 사용하면 된다.
이때 이미 리스트가 정렬되어 있다면 320 칼로리보다 크거나 같은 요리가 나왔을 때 작업을 중단하면 됩니다.
이런 작업을 takeWhile을 사용하여 해결할 수 있습니다.
List<Dish> slicedMenu1 = specialMenu.stream() .takeWhile(dish -> dish.getCalories() < 320) .collect(toList());
dropWhile 활용
dropWhile은 takeWhile과 정반대의 작업을 수행합니다.
dropWhile은 프레디케이트가 처음으로 거짓이 되는 지점까지 발견된 모든 요소를 버립니다.
스트림 축소
limit 메서드 활용
limit(n)은 최대 요소 n개를 반환합니다.
skip 메서드 활용
skip(n)은 처음 n개 요소를 제외한 스트림을 반환합니다.
매핑
특정 객체에서 특정 데이터를 선택하는 작업으로 데이터 처리에 매우 매우 자주 활용되는 연산입니다.
map이라는 이름을 가지고 있어서 Collection의 map과 좀 혼란이 있어서 예전에 이해하기 어려웠습니다.
mapping의 약자로 이해하면 좋습니다.
map 메서드
새로운 버전을 만든다라는 개념으로 변환에 가깝습니다.
mapping의 약자입니다.
Dish 객체를 받아 이름으로 변환하여 스트림의 요리명을 추출하는 코드입니다.
List<String> dishNames = menu.stream() .map(Dish::getName) .collect(toList());
스트림의 평면화
만약 ["Hello", "World"] 리스트가 있다면 결과로 ["H", "e", "l", "o", "w", "r", "d"]를 포함하는 리스트를 반환해야 한다면 어떻게 해야 할까요?
리스트에 있는 각 단어를 문자로 mapping 하고 distinct로 중복된 문자를 필터링하면 해결할 수 있다고 생각할 수 있습니다.
하지만 map으로 전달한 람다는 각 단어의 String []을 반환하고 우리가 원하는 것은 Stream입니다.
이러한 문제를 faltMap을 사용하면 해결할 수 있습니다.
List<String> words = Arrays.asList("Hello", "World"); words.stream() .map(word -> word.split("")) .flatMap(Arrays::stream) .distinct() .collect(Collectors.toList());
flatMap은 하나의 평면화된 스트림을 반환합니다.
검색과 매칭(최종 연산)
allMatch, anyMatch, noneMatch, findFirst, findAny 등 다양한 유틸리티 메서드를 제공합니다.
검색과 매칭은 특정 속성이 데이터 집합에 있는지 여부를 검색할 때 주로 사용됩니다.
findFirst와 findAny가 둘 다 존재하는 이유
병렬 실행 시에는 첫 번째 요소를 찾기 힘들기 때문에 findAny를 활용합니다.
리듀싱
리듀싱은 의미로 이해하면 제거한다는 의미로 이해가 됩니다.
하지만 모든 스트림 요소를 처리해서 값을 도출하는 데 사용되며 마치 종이(스트림)를 반복해서 접는 것과 비슷하다는 의미로 폴드라고도 부릅니다.
리듀스 연산을 사용하면 "메뉴의 모든 칼로리의 합", "메뉴에서 가장 높은 요리"를 얻을 수 있습니다.
다음은 스트림의 모든 요소를 더하는 과정입니다.
int sum = numbers.stream().reduce(0, (a,b) -> a + b);
이때 0은 초깃값 , a + b는 람다 표현식을 활용하여 두 수를 더하는 연산입니다.
0부터 시작해서 점점 값을 누적해나가는 방식입니다.
'Java > 모던자바인액션요약' 카테고리의 다른 글
병렬 데이터 처리와 성능 (0) 2022.08.29 스트림으로 데이터 수집 (0) 2022.08.23 스트림 소개 (0) 2022.08.15 람다 표현식 (0) 2022.08.10 동작 파라미터화 코드 전달하기 (0) 2022.08.06