LostCatBox

about-java-stream-api

Word count: 547Reading time: 3 min
2025/12/12 Share

왜?

코테에서 가장 자주 사용하는 Stream API에 대해 공부해보낟.

Stream API의 특징

  • 원본 데이터를 변경하지않는다.
  • Stream은 일회용이다.
  • 내부 반복으로 작어블 처리한다.

연산 종류

  • 생성하기
  • 가공하기
  • 결과만들기

예시

1
2
3
4
5
6
7
8
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream() // 생성하기
.filter(s -> s.startsWith("c")) // 가공하기
.map(String::toUpperCase) // 가공하기
.sorted() // 가공하기
.count(); // 결과만들기

함수형 인터페이스와 람다

Stream 연산들은 매개변수로 함수형 인터페이스(Functional Interface)를 받도록 되어있다.

람다

람다식(Lambda Expression)이란 함수를 하나의 식(expression)으로 표현한 것이다. 함수를 람다식으로 표현하면 메소드의 이름이 필요 없기 때문에, 람다식은 익명 함수(Anonymous Function)의 한 종류라고 볼 수 있다.

1
2
3
4
5
6

// 람다 방식
(매개변수, ... ) -> { 실행문 ... }

// 예시
() -> "Hello World!";

Java에서 제공하는 함수형 인터페이스

Supplier<T>

  • 매개변수없음
  • 반환값 존재
  • T get() -> 반환값 반환

Consumer<T>

  • 매개변수 있음
  • 반환값 없음
  • Accept(T t) -> 함수 수행

Function<T, R>

  • 매개변수 있음
  • 반환값 있음
  • R apply(T t) -> 함수 수행 및 반환값 반환

Predicate<T>

  • 매개변수 있음
  • Boolean으로만 반환값 있음
  • boolean test(T t) ->함수 수행 및 Boolean 반환값 반환

메서드 참조 문법

람다식을 더 짧게 표현

https://inpa.tistory.com/entry/JAVA8-%E2%98%95-%EB%9E%8C%EB%8B%A4%EC%8B%9D%EC%9D%84-%EB%8D%94-%EC%A7%A7%EA%B2%8C-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%B0%B8%EC%A1%B0Method-Reference

1
2
3
4
5
//기존 람다식
(x, y) -> Math.max(x,y)

// 메서드 참조 문법
Math::max
종류 람다 표현식 메서드 참조
정적 메서드 참조 (x) -> ClassName.method(x) ClassName::method
인스턴스 메서드 참조 (x) -> obj.method(x) obj::method
매개변수의 메서드 참조 (obj, x) -> obj.method(x) ClassName::method
생성자 참조 (x, y) -> new ClassName(x, y) ClassName::new

stream

스트림 종류

일반 스트림

  • Stream<T> // 참조 타입용 스트림 -> boxed() 반드시 필요함.

원시 스트림

  • IntStream // int 전용

  • LongStream // long 전용

  • DoubleStream // double 전용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//생성
//- Collection의 Stream생성
//- Array에서 Stream생성
//- 원시 값에서 Stream생성
List<Integer> list = Arrays.asList(1, 2, 3);
Stream<Integer> stream = list.stream();
Stream<String> stream1 = Arrays.stream(new String[]{"a", "b"});
IntStream stream2 = Arrays.stream(new int[]{1, 2, 3});
IntStream range = IntStream.range(4, 10);


// 가공
// filter - 내부적으로 Predicate 함수형 인터페이스를 받음.
stream1.filter((str)->str.equals("a"));
stream2.filter((i)-> 2<i);
// map - 요소들을 변환하여 새로운 Stream을 형성하는 연상이다.
stream.map(i-> i*2);
stream1.map(String::toUpperCase);
stream2.map(Integer::hashCode);
// sorted - 정렬, Comparator를 넘길수도있다.
stream1.sorted(Comparator.reverseOrder()); //역순
stream2.sorted();
// distinct - 중복 제거
stream1.distinct();
// mapToXXX - 원시 스트림과 일반 스트림간의 전환할떄 사용한다.
stream1.mapToInt(Character::codePointOf);
stream2.mapToObj(String::valueOf);


//최종 연산
// max, min, sum, average, count
stream1.max(Comparator.comparing(String::length));
stream2.max().orElse(0);

// collect - List나 Set, Map, 등 다른 종류의 결과로 수집하고 싶은 경우
//Collector : 인터페이스, collect의 파라미터는 이 인터페이스를 구현해야한다.
//Collectors : 클래스, static메소드로 미리 작성된 컬렉터를 제공한다.
stream1.collect(Collectors.toSet());

// match - 특정 조건 충족하는지 검사 Boolean반환
stream.allMatch((i)-> i.equals(1));
stream1.anyMatch((str)->str.equals("a"));
stream2.noneMatch((i)->i==0);

// forEach - 특정 연상 수행
stream.forEach(System.out::println);
CATALOG
  1. 1. 왜?
  2. 2. Stream API의 특징
  3. 3. 연산 종류
  4. 4. 함수형 인터페이스와 람다
    1. 4.1. 람다
    2. 4.2. Java에서 제공하는 함수형 인터페이스
      1. 4.2.1. Supplier<T>
      2. 4.2.2. Consumer<T>
      3. 4.2.3. Function<T, R>
      4. 4.2.4. Predicate<T>
    3. 4.3. 메서드 참조 문법
  5. 5. stream