Stream 인터페이스

import java.util.stream;

public interface Stream<T> extends BaseStream<T,Stream<T>>{
	Stream<T> filter(Predicate<? super T> predicate)
	<R> Stream<R> map(Function<? super T,? extends R> mapper);
	Stream<T> sorted();
	Stream<T> sorted(Comparator<? super T> comparator);
	Stream<T> distinct();
	Stream<T> limit(long maxSize);
	Stream<T> skip(long n);
	<R,A> R collect(Collector<? super T,A,R> collector);
	<R> R collect(Supplier<R> supplier,BiConsumer<R,? super T> accumulator,BiConsumer<R,R> combiner);
	void forEach(Consumer<? super T> action);
	long count();
	Optional<T> reduce(BinaryOperator<T> accumulator);
	T reduce(T identity,BinaryOperator<T> accumulator);
	<U> U reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator<U> combiner);
	boolean anyMatch(Predicate<? super T> predicate);
	boolean allMatch(Predicate<? super T> predicate);
	boolean noneMatch(Predicate<? super T> predicate);
	// ...
}
  • Java8 부터 도입된 기능으로, 컬렉션 데이터를 선언적(선언형 프로그래밍) 방식으로 처리할 수 있게 해주는 API
  • 리스트나 배열 같은 데이터를 반복문 없이 간결하게 필터링, 매핑, 정렬, 집계 등의 연산을 수행할 수 있게 됨
Stream : 데이터 원본(Collection, 배열 등)에 대해 연산을 수행하는 파이프라인
중간 연산 : 스트림을 변형하지만 결과를 반환하지 않음(filter, map, sorted등)
최종 연산 : 스트림을 소모하고 결과를 반환함(collect, forEach, count, reduce 등)
지연 연산 : 최종 연산이 호출되기 전까지 중간 연산은 실행 되지 않음(lazy evaluation)

 

중간 연산 (Intermediate)

필터링 📌

Stream<T> filter(Predicate<? super T> predicate);
  • 조건 필터링
  • Predicate : boolean 값을 반환하는 함수형 인터페이스 (test(T t) 메서드 존재)
  • 조건을 통과한 요소로 이뤄진 새로운 스트림
  • Predicate는 람다식이나 메서드 참조로 전달 가능
Predicate<String> startsWithA = s → s.startsWith(”A”);
names.stream().filter(startsWithA).forEach(System.out::println);
Predicate<Object> p = obj -> obj.toString().length() > 3;
Stream<String> s = Stream.of("hi", "hello", "world");
s.filter(p).forEach(System.out::println); // hello, world
  1. 스트림의 각 요소에 대해 predicate.test(element)를 호출
  2. true를 반환하는 요소만 다음 단계로 넘어감
  3. 최종연산을 호출할 때 실제 실행됨(지연 실행 lazy evaluation)

 

변환 📌

<R> Stream<R> map(Function<? super T,? extends R> mapper);
  • 요소 변환
list.stream().map(String::toUpperCase)

 

정렬 📌

Stream<T> sorted(); // 자연 순서 정렬(natural order), Comparable 구현 필요
Stream<T> sorted(Comparator<? super T> comparator); // 사용자 지정 기준 정렬
  • 정렬
  • 호출 당시에는 실제 정렬은 수행되지 않음, 최종 연산을 해야 정렬 결과 평가됨
List<String> names = List.of("Charlie", "Alice", "Bob");

names.stream()
     .sorted()
     .forEach(System.out::println);

// 출력:
// Alice
// Bob
// Charlie
// 오름차순 정렬
List<Integer> nums = List.of(5, 3, 9, 1);

nums.stream()
    .sorted((a, b) -> a - b)
    .forEach(System.out::println);

// 또는 Comparator 사용:
nums.stream()
    .sorted(Comparator.naturalOrder())
    .forEach(System.out::println);

// 내림차순 정렬
nums.stream()
    .sorted(Comparator.reverseOrder())
    .forEach(System.out::println);

 

중복 제거 📌

Stream<T> distinct();
  • 중복 제거
  • equals() 를 기준으로 중복 제거함

 

자르기 📌

Stream<T> limit(long maxSize);
  • 앞에서 최대 maxSize개만 남김

 

건너뛰기 📌

Stream<T> skip(long n);
  • 앞에서 n개 요소를 건너뜀

 


 

최종 연산 (Terminal)

<R,A> R collect(Collector<? super T,A,R> collector);

// 사용자 정의 방식으로 수집(병렬 처리 포함)
<R> R collect(Supplier<R> supplier,BiConsumer<R,? super T> accumulator,BiConsumer<R,R> combiner);
  • 수집
  • Collectors.toList()와 같은 팩토리와 함께 사용하여 결과 수집
list.stream().collect(Collectors.toList());

 

소비형(Consuing) 연산 📌

void forEach(Consumer<? super T> action);
  • 각 요소에 동작
  • 순서 보장 ❌

 

long count();
  • 요소 개수 반환

 

축소(Reduction) 연산 📌

// 요소들을 초기값 없이 누적 처리
Optional<T> reduce(BinaryOperator<T> accumulator);

// 초기값 포함 누적
T reduce(T identity,BinaryOperator<T> accumulator);

// 병렬 처리에 적합한 복잡한 누적 로직 처리
<U> U reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator<U> combiner);
  • 누적 계산
list.stream().reduce((a, b) -> a + b); // 초기값 없이 누적
list.stream().reduce(0, Integer::sum); // 초기값 포함 누적

 

조건 검사 📌

boolean anyMatch(Predicate<? super T> predicate);
  • 하나라도 조건을 만족하면 true

 

boolean allMatch(Predicate<? super T> predicate);
  • 모두 조건을 만족해야 true

 

boolean noneMatch(Predicate<? super T> predicate);
  • 모두 조건을 만족하지 않아야 true

'Java' 카테고리의 다른 글

VO 🆚 DTO  (0) 2025.05.02
Serializable 인터페이스  (0) 2025.05.02
Predicate 인터페이스  (0) 2025.05.02
참조타입 (reference type)  (1) 2025.05.01
기본타입 (primitive type)  (0) 2025.05.01