Stream API란 Java8에서 추가된 Collection입니다.
이 API를 사용하면 데이터를 함수형 프로그래밍의 스타일로 다루며
함수형 프로그래밍의 장점을 활용해 가독성이 높은 코드를 작성할 수 있습니다.
// 즉, Stream API를 사용하면 유지보수 또한 훨씬 쉬워지겠죠?
Stream API의 주요 특징
1. Stream(스트림) :
스트림은 데이터 요소의 연속적인 흐름으로, 컬렉션, 배열, I/O자원 등을 대상으로 합니다.
스트림은 요소들의 조합을 다루고 변환하는 함수형 스타일의 인터페이스를 제공합니다.
2. Internal Iteration (내부 반복) :
기존의 Iterator과는 달리, 스트림 API는 내부반복을 사용합니다.
즉 개발자가 컨트롤하는 Iterator과는 달리, 스트림이 알아서 내부적으로 요소를 반복하며 연산을 수행한다는 의미입니다.
3. 함수형 프로그래밍 :
스트림 API는 함수형 인터페이스와 람다식을 활용하여 데이터를 처리합니다.
이를 통해 간결하고 읽기 쉬운 코드를 작성할 수 있습니다.
4. 중간연산, 그리고 최종연산 :
스트림 연산은 최종 연산과 중간 연산으로 나뉩니다.
중간연산은 여러 스트림을 연결하여 새로운 스트림을 반환(return) 하며,
최종 연산은 스트림의 요소를 소비해 결과를 도출합니다.
5. 지연연산 :
스트림 연산은 지원연산을 지원합니다. 중간연산은 실제 수행되지 않고,
최종연산이 호출 될 때까지 연기되는 형태입니다!
이를 통해 연산의 최적화 및 효율적인 메모리 사용이 가능합니다.
6. 병렬 처리 지원 :
병렬 스트림을 사용하여 멀티스레드 환경에서 요소를 병렬로 처리할 수 있습니다.
7. 다양한 연산 제공 :
'map', 'filter', 'reduce' , 'forEach', 'collect' , 'distinct' , 'sorted', 'limit' , 'skip' 등 다양한 연산을 제공하여,
데이터를 전환, 필터링, 정렬, 제한하는 등의 작업을 수행할 수 있습니다.
stream 만들고 -> 중간연산 -> 최종연산의 형태를 거칩니다.
몇 가지 유용한 메서드 목록들을 공유해 드릴게요.
-⑴스트림 생성 메서드 -
ㆍ Arrays.stream(); 주어진 배열로 스트림을 생성합니다. ↓
int[] numbers = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(numbers);
ㆍList.stream(); 주어진 리스트로 스트림을 생성합니다. ↓
List<String> names = Arrays.asList("Kim", "Lee","Park");
Stream<String> stream = names.stream();
ㆍStream.of(); 주어진 요소들로 스트림을 생성합니다 ↓
Stream<Integer> stream = Stream.of(1,2,3,4,5);
-⑵중간 연산 메서드 -
ㆍFiltering (필터링)
filter(); 주어진 조건에 맞는 요소들로 스트림을 필터링합니다. ↓
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<Integer> evenNumbers = numbers.stream()
.filter(n->n%2 ==0 )
.collect(Collectors.toList());
System.out.println(evenNumbers); // [2,4,6,8,10]
ㆍDistincs (중복제거)
distinct(); 중복 요소를 제거한 스트림을 반환합니다. ↓
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5, 5);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // [1, 2, 3, 4, 5]
ㆍSkip(건너뛰기)
skip(n) ; 처음 'n' 개의 요소를 건너뛴 스트림을 반환합니다. ↓
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> afterSkipping = numbers.stream()
.skip(3)
.collect(Collectors.toList());
System.out.println(afterSkipping); // [4, 5]
ㆍFindFirst (첫 번째 요소 찾기)
findFirst(); 스트림의 첫 번째 요소를 찾습니다. ↓
List<Integer> numbers = Arrays.asList(1, 3, 5, 6, 7, 8, 9);
Optional<Integer> firstEven = numbers.stream()
.filter(n -> n % 2 == 0)
.findFirst();
if (firstEven.isPresent()) {
System.out.println(firstEven.get()); // 6
} else {
System.out.println("짝수 없음");
}
ㆍLimit (제한)
limit( n) ; 스트림의 크기를 최대 'n'으로 제한합니다. ↓
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> limitedList = numbers.stream()
.limit(3)
.collect(Collectors.toList());
System.out.println(limitedList); //[1, 2, 3]
ㆍ Sorted (정렬)
sorted(); 요소들을 기본 정렬 순서에 따라 정렬합니다.
sorted( a); 주어진 비교자에 따라 요소들을 정렬합니다. ↓
List<Integer> numbers = Arrays.asList(5, 3, 9, 1, 6);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedNumbers); //[1, 3, 5, 6, 9]
ㆍMap (매핑)
map(Function < a, b> map) ; 각 요소를 주어진 함수에 매핑해 새로운 값을 return 합니다. ↓
List<String> names = Arrays.asList("Kim", "Kang", "No");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(nameLengths); //[3, 4, 2]
-⑶최종 연산 메서드-
ㆍ Count (요소 개수 계산)
count(): 스트림의 요소 개수를 반환합니다 ↓ .
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count();
System.out.println(count); // 5
ㆍ Sum (요소 합계)
sum(): 숫자 요소의 합계를 반환합니다. ↓
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
System.out.println(sum); // 15
ㆍ Average (평균)
average(): 숫자 요소의 평균 값을 반환합니다 ↓ .
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
double average = numbers.stream().mapToDouble(Integer::doubleValue).average().orElse(0.0);
System.out.println(average); // 3.0
ㆍ Max (최댓값)
max(Comparator<T> comparator): 요소 중 최댓값을 반환합니다. ↓
List<Integer> numbers = Arrays.asList(3, 7, 2, 8, 5);
Optional<Integer> max = numbers.stream().max(Integer::compareTo);
max.ifPresent(value -> System.out.println("최댓값: " + value)); // 최댓값: 8
ㆍ Min (최솟값)
min(Comparator<T> comparator): 요소 중 최솟값을 반환합니다. ↓
List<Integer> numbers = Arrays.asList(3, 7, 2, 8, 5);
Optional<Integer> min = numbers.stream().min(Integer::compareTo);
min.ifPresent(value -> System.out.println("최솟값: " + value)); // 최솟값: 2
ㆍ ForEach (각 요소에 대한 동작 수행)
forEach(Consumer<T> action): 각 요소에 대해 주어진 동작을 수행합니다. ↓
List<String> names = Arrays.asList("A", "B", "C");
names.stream().forEach(System.out::println);
// A
// B
// C
ㆍ Collect (스트림 요소 수집)
collect(Collector<? super T, A, R> collector): 스트림의 요소를 수집하여 컬렉션 또는 다른 종류의 결과로 반환합니다. ↓
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collected = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
System.out.println(collected); // [2, 4]
댓글