[JAVA] Stream

김가희·2023년 3월 3일

다음 글은 해당 링크를 보며 배운 내용을 정리하였습니다.
https://hbase.tistory.com/171

❓ Stream?

컬렉션 요소들을 순회하여 처리할 수 있는 코드 패턴

장점

  1. 람다식과 함께 사용하여 간결하다.
  2. 내부 iterator를 사용하여 병렬 처리가 쉽다.

사용 방법은 생성 -> 가공 -> 소비를 순서대로 설명하겠다. 이 순서가 은근 중요하다.

1️⃣ 스트림을 생성해보자

1. 컬렉션 객체. stream() //스트림 객체(Stream<> name)을 생성해준다.

2. Arrays.stream(array) //배열 -> Stream

3. Arrays.stream(array, start, end) //	배열의 Start <= ~ < End -> Stream

4. Stream<>builder()  //builder생성
			.add() //데이터 넣기
            .build(); //build
            
5. Stream<String> name = Stream.generator(() -> "Hello").limit(5)
//무한으로 "Hello"를 찍어낸다.

6. Stream<Integer> name = Stream.iterator(100, n -> n + 10).limit(5)
// + 10을 반복하여 찍어낸다. 100, 110, 120...,140

7. Pattern.complie(",").splitAsStream("문자열") //split한 문자를 stream으로!

8. Stream.concat(stream1, stream2)로 붙일 수 있다.

오토박싱, 언박싱?

박싱 : 자바 기본타입 (int, long, float, double, boolean) -> Wrapper
언박싱 : Wrapper -> 자바 기본타입

이러한 오토박싱이 일어나면 오버헤드 발생으로 성능 저하가능성이 있다. 그러므로 동일 타입 연산으로 성능을 높여야 하는데 스트립에서 이러한 오토박싱을 막으려면

IntStream name = IntStream.range(1,10);

처럼 타입을 정해주면 된다.
하지만 이렇게 사용하면 제네릭(Stream<>)이 사용하는 메소드 들을 사용할 수 없는데, 이를 위해서 .boxed()를 붙여줘야한다.
(대표적으로 사용할 수 없는 메소드는 collect()가 있다.)

참고로 int 배열을 스트림으로 바꾸면 자동으로 IntStream이 된다. 그러므로 boxed()해줘야한다.

2️⃣ 스트림을 가공해보자

가공한다? => 가공된 결과를 Stream 으로 return

  1. filter()
    Stream 에서 나오는 데이터에서 특정 테이터 들만 골라낸다.
    .filter(v -> ((v % 2 == 0))

  2. map()
    데이터를 변경하여 return
    .filter(v -> v * 10)

  3. flatMap()
    중첩된 구조를 한단계 적은 컬렉션에 대한 스트림으로 만들어준다.
    만약 list들로 이루어진 List가 있다면 이 각각의 list를 합쳐서 하나의 stream 으로 보내주는 것이다. 이렇게 한단계 낮은 컬렉션 스트림으로 만드는것을 플랫트닝이라고 한다.

  4. peek()
    디버깅목적이 제일 크며 안에있는 식을 적용만 한다?
    forEach같은경우는 return이 void라서 마지막에 사용할 수 있지만 peek같은 경우는 최종 처리 메소드는 아니다.

  5. sorted()
    오름차순으로 정렬해준다.

3️⃣ 스트림을 소비해보자.

  1. 기본적인 연산
    .sum() .count() .max() .min() .average() 다 사용가능하다.

  2. reduce()

  3. collect()
    뽑아져 나오는 데이터를 Collector에 모아둔다.
    collect(Collectors.toSet()) 처럼.
    형태는 Set말고도 사용가능하다.

  4. joining()
    결과값을 이어붙인다.
    joining(중간, start, end)로 문자열로 붙일 수 있다.

  5. forEach()
    나오는 값에 대해 작업을 하고 싶을 떄 사용한다.

  • collectingAndThen(A, B)
    A로 collecting한 결과를 B에 인자로 사용한다.

사용하며 느낀점

stream을 쓰면서 오히려 코드가 더러워진 경우가 있었다. (아래링크 참고)
https://velog.io/@kimgaheeme/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B3%A0%EB%93%9D%EC%A0%90-Kit-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98

그러므로 쓸때 안쓸때 구분해서 쓰는게 좋을것 같다. 특히 stream을 통해 이득을 취할수 있을지, 메소드를 통해서 좀더 유연하게 작성할 수 있을지 없을지를 구분하자..

profile
안드로이드 개발자

0개의 댓글