컬렉션 등의 데이터를 함수형 스타일로 처리할 수 있도록 제공된 데이터 처리 추상화 도구
1. 스트림 API란?
Java 8에서 도입된 기능으로, 컬렉션이나 배열 등의 데이터를 함수형 스타일로 처리할 수 있게 해주는 데이터 처리 도구다. 이를 통해 데이터를 필터링, 매핑, 정렬, 집계 등의 연산을 간결하고 효율적으로 수행할 수 있다. 스트림은 데이터를 변경하지 않고, 재사용할 수 없으며, 중간 연산과 최종 연산으로 나뉜다.
2. 예제
1. filter, toList, count
public class CountApp {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> r1 = names.stream().filter(name -> name.length() > 3).toList();
r1.forEach(s -> System.out.println(s));
long r2 = names.stream().filter(name -> name.length() > 3).count();
System.out.println(r2);
}
}
- filter
filter
는 스트림의 요소 중 조건을 만족하는 것만 추출하는 중간 연산자- 주어진 조건식에 맞는 요소들만 필터링하여 새로운 스트림을 반환한다.
filter(name -> name.length() > 3)
은 이름 길이가 3보다 긴 문자열만 추출한다.
- toList
toList
는 스트림의 요소들을 리스트로 변환하는 최종 연산자- 스트림을
List
로 수집하여 반환한다.
- count
count
는 스트림의 요소 개수를 셈으로써 결과를 반환하는 최종 연산자- 조건을 만족하는 요소의 개수를 반환한다.
2. map
public class MapApp {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> newNames = names.stream().map(name -> name.toLowerCase()).filter(name -> name.length() > 3).toList();
newNames.forEach(name -> System.out.println(name));
}
}
- map
map
은 각 요소를 변환하는 중간 연산자- 주어진 함수에 따라 스트림의 각 요소를 변환하여 새로운 스트림을 생성한다.
map(name -> name.toLowerCase())
로 각 이름을 소문자로 변환한다.
3. sum, reduce
public class ReduceApp {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1, 2, 3, 4);
int sum = nums.stream().mapToInt(x -> x).sum();
System.out.println(sum);
int sum2 = nums.stream().reduce(5, (prev, next) -> {
System.out.println("prev: " + prev);
System.out.println("next: " + next);
System.out.println("---------------");
return prev + next;
});
System.out.println(sum2);
}
}
- mapToInt
mapToInt
는 스트림의 요소들을int
값으로 변환하는 중간 연산자mapToInt(x -> x)
는 리스트의 요소들을 그대로int
형으로 변환한다.sum
메서드를 사용하려면IntStream
으로 변환해야 한다.
- sum
sum
은mapToInt
로 변환된int
스트림의 모든 값을 더하여 결과를 반환하는 최종 연산자
- reduce
reduce
는 스트림의 요소들을 순차적으로 결합하여 하나의 값을 생성하는 최종 연산자reduce(5, (prev, next) -> prev + next)
에서는 두 요소를 합산하는 방식으로reduce
를 사용하며 초기값 5부터 시작하여 각 요소와 결합한다.
4. sort, distinct
public class SortApp {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(5, 3, 1, 4, 2);
nums.stream().sorted().distinct().forEach(System.out::println);
}
}
- sort
sort
는 스트림의 요소들을 정렬하는 중간 연산자- 기본적으로 오름차순으로 정렬되며, 내림차순 정렬을 원하면
Comparator.reverseOrder()
를 사용할 수 있다.
- distinct
distinct
는 스트림의 중복 요소를 제거하는 중간 연산자- 요소들 중 중복되는 값을 제거하고 고유한 값만을 포함하는 스트림을 반환한다.
- forEach
forEach
는 스트림의 각 요소에 대해 주어진 동작을 수행하는 최종 연산자- 각 요소에 대해
System.out::println
을 실행하여 출력한다.
5. group
public class GroupApp {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Bavid", "anna");
// Map<Character, List<String>>
var groupData = names.stream().map(String::toUpperCase).collect(Collectors.groupingBy(s -> s.charAt(0)));
System.out.println(groupData);
}
}
- collect
collect
는 스트림의 결과를 컬렉션으로 변환하는 최종 연산자Collectors.groupingBy
를 사용하여 스트림의 요소들을 그룹화하여Map
형태로 반환한다.
- groupingBy
groupingBy
는 스트림의 요소를 특정 기준에 따라 그룹화하는 중간 연산자- 문자열의 첫 번째 문자를 기준으로 이름들을 그룹화하여
Map<Character, List<String>>
형태로 반환한다.
Share article