Java 스트림

김정훈·2024년 5월 2일

Java

목록 보기
31/48

1. 스트림이란?

java.util.stream

  • 데이터 소스가 무엇이든 간에 같은 방식으로 다룰 수 있게 데이터를 추상화 하고 데이터를 다루는데 자주 사용되는 메서드들을 정의해 놓음

배열 👉 java.util.Arrays
컬렉션 👉 java.util.Collections

  • 배열이든, 컬렉션이든 Stream 객체로 변환하면 동일한 방식으로 처리 가능

배열과 리스트는 처리방법이 다르다. 그렇지만 Stream을 사용하여 Stream객체로 생성하면 동일한 반식으로 처리가 가능.

public class Ex03 {
    public static void main(String[] args) {
        String[] fruits = {"apple", "orange", "mango", "melon"};
        Arrays.stream(fruits).map(s -> "*" + s + "*").map(String::toUpperCase).forEach(System.out :: println);
    }
}
public class Ex04 {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple","orange","mango","melon");
        fruits.stream().map(s -> "*" + s + "*").map(String :: toUpperCase).forEach(System.out :: println);
    }
}
  • 편의 기능
  • 스트림은 데이터 소스를 변경하지 않는다.(원데이터는 그대로)
  • 스트림은 일회용이다.
public class Ex05 {
    public static void main(String[] args) {
        int[] nums = {22,11,15,35,40,77};
        IntStream stm = Arrays.stream(nums);

        int total = stm.map(x -> x * x).sum();
        System.out.println(total);

        /*
        int total = stm.map(x -> x * x * x).sum();
        System.out.println(total2);
        오류발생 stream은 일회용객체이기 때문이다.
         */
    }
}
  • 스트림은 작업을 내부 반복으로 처리한다.

2. 스트림만들기

1) 컬렉션

	Collection
		Stream stream()

2) 배열

	Arrays
		static stream(....)

3)

	Stream
		.of(T... )

of는 거의 사용하지않음.

public class Ex09 {
   public static void main(String[] args) {
       long cnt = Stream.of("이름1","이름2","이름3","이름4").count();
       System.out.println(cnt);

   }
}
  1. 스트림의 연산

1) 중간연산
- 스트림 중간 부분에 정의된 메서드
- 반환값이 Stream인 형태 (Stream, IntStream, LongStream, DoubleStream ..))
- 최종 연산이 호출 될 때까지는 연산 ❌

2) 최종연산
- 호출 되면 중간연산도 함께 수행, 연산 종료
- 가장 끝에 추가된 메서드
- 반환값이 Stream이 아닌 형태

3) 지연된연산
중간 연산은 최종 연산이 호출되어야 스트림을 소비하면서 연산이 진행 된다.

public class Ex08 {
    public static void main(String[] args) {
        int[] nums = {22, 11, 10, 2, 6, 8, 33};
        Arrays.stream(nums).map(x -> x * x).filter(x -> x % 2 == 1).forEach(System.out :: println);
        //forEach를 작성하야 최종연산이 가능하게된다.
    }
}
  1. 기본자료형을 다루는 스트림

IntStream
LongStream
DoubleStream
👉 오토박싱, 언박싱이 발생 X -> 성능상 이점
👉 숫자 관련 편의 기능 추가(예 - 통계 관련 기능)

일반 스트림 -> 기본 자료형 스트림으로 변환 메서드
mapToInt : IntStream
mapToLong : LongStream
mapToDouble : DoubleStream

기본 자료형 스트림 -> 일반 스트림 변환 메서드
boxed()

예)
IntStream 👉 Stream
LongStream 👉 Stream
DoubleStream

👉 숫자(정수, 실수) 관련 편의 기능 제공 (일반 스트림은 숫자가 아닌 다른 자료형도 다루므로 숫자에 한정한 기능은 제공❌)
👉 연산 성능 향상

IntStream에는 정렬기능 sorted() 메서드가 1개만 정의 기본정렬 기준 정렬(java.lang.Comparable..)
👉 그러면 기본 정렬 기준외에 다른 기준으로 정렬은 안되나 ?
그런데 일반 스트림 Stream에서는 sorted()와 sorted(comparable

참고)
IntStream
static IntStream range(시작번호, 종료 번호(미만))
rangeClosed(시작번호, 종료 번호(이하))
IntSummaryStatistics summaryStatistics()

  public class Ex12 {
    public static void main(String[] args) {
        int[] nums = {33, 10, 5, 1, 3, 88, 100, 10};
        int[] nums2 = Arrays.stream(nums).sorted().toArray();
        System.out.println(Arrays.toString(nums2));
        int[] nums3 = Arrays.stream(nums).boxed().sorted(Comparator.reverseOrder()).mapToInt(x -> x).toArray();

        System.out.println(Arrays.toString(nums3));

    }
}

스트림 활용
1. 생성하기
Collection::stream() : 일반 스트림
Arrays.stream(...) : 일반스트림 + 기본 자료형 스트림

Stream.of(T.... ) : 일반스트림, 기본 자료형 스트림

1) 특정 범위의 정수
기본 자료형 스트림(IntStream, LongStream)
횟수가 정해진 반복을 할때
range(....)
rangeClosed(...)

2) 임의의 수
java.util.Random
무한 스트림 - 갯수 제한이 필요
IntStream ints(); : 정수범위 난수
LongStream longs() :
DoubleStream doubles() : 실수 범위 난수

3) 람다식 - iterate(), generate()
- 무한스트림

4) 두 스트림의 연결 - concat()

  1. 스트림의 중간 연산
    1) skip(), limit()

limit() : 갯수 제한
skip() : 건너 뛰기

2) filter(), distinct()
filter(Predicate ...) : 스트림을 걸러주는 기능

distinct() : 중복 제거
- 중복 제거 기준 : equals() and hashCode()

3) sorted()
- 정렬 : 기본 정렬 기준 java.lang.Comparable int compareTo(...)
- sorted(Comparator ....)
- 대안적인 기준 : java.util.Comparator :: int compare(....)

4) map()
map(Function<T,R> ...) : 변환 메서드

5) peek()
- forEach와 매개변수가 동일
- Stream peek(Consumer ... ) : 중간 연산 : 중간에 값을 확인할 경우 많이 사용
- void forEach(Consumer ...) : 최종 연산 : 최종적으로 출력할때 사용

6) mapToInt(), mapToLong(), mapToDouble()

profile
안녕하세요!

0개의 댓글