[Java] 14장 - 스트림

N’oublie pas de t’aimer·2025년 1월 7일

Java

목록 보기
7/18

스트림

다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것이다.
쉽게 말하면 데이터의 연속적인 흐름.

데이터 소스 -> Stream -> 중간 작업 -> 최종 작업

중간 연산: 연산 결과가 스트림인 연산. 반복적으로 적용 가능
최종 연산: 연산 결과가 스트림이 아닌 연산. 단 한번만 적용 가능(스트림의 요소를 소모)

예시

stream.distinct().limit(5).sorted().forEach(System.out::println)

distinct: 중복 제거
limit(n): n개로 자르기
forEach: stream의 요소를 하나씩 꺼내기

Stream의 특징

  • 스트림은 데이터 소스로부터 데이터를 읽기만 할 뿐 변경하지 않는다.
List<Integer> list = Arrays.asList(3, 1, 5, 4, 2);
List<Integer> sortedList = list.stream().sorted()
						.collect(Collectors.toList()); // 새로운 list에 저장
System.out.println(list); // [3, 1, 5, 4, 2]
System.out.println(sortedList); // [1, 2, 3, 4, 5]
  • 스트림은 iterator처럼 일회용이다. (필요하면 다시 스트림을 생성해야 함)
strStream.forEach(System.out::println); // 모든 요소를 화면에 출력(최종 연산)
int numOfStr = strStream.count(); // 에러. 스트림이 이미 닫혔음.
  • 최종 연산 전까지 중간 연산이 수행되지 않는다.
IntStream intStream = new Random().ints(1, 46); // 1~45 범위의 무한 스트림
intStream.distinct().limit(6).sorted() // 중간 연산
			.forEach(i -> System.out.print(i + ", ")); // 최종연산

무한 스트림에 대해서 중복을 제거하고 자르고 정렬하는 연산을 할 수 있는 이유는 지연된 연산 때문이다.

  • 작업을 내부 반복으로 처리한다.
void forEach(Consumer<? super T> action) {
	Objects.requireNonNull(action); // 매개변수의 널 체크
    
    for(T t : src) 	// 내부 반복(for문을 메서드 안으로 넣음)
    	action.accept(T);
}
  • 스트림의 작업을 병렬로 처리 - 병렬스트림
    멀티 쓰레드를 사용하여 작업하는 것
Stream<String> strStream = Stream.of("dd", "aa", "CC", "cc", "b");
int sum = strStream.parallel()
			.mapToInt(s -> s.length()).sum(); // 모든 문자열 길이의 합
  • 기본형 스트림 - IntStream, LongStream, DoubleStream
    오토박싱 & 언박싱의 비효율이 제거된다. (Stream 대신 IntStream 사용)
    숫자와 관련된 유용한 메서드를 Stream보다 더 많이 제공한다.
profile
매일 1퍼센트씩 나아지기 ୧(﹒︠ ̫ ̫̊ ̫﹒︡)୨

0개의 댓글