Post

[JAVA]자바 Stream 사용방법 1편(생성하기)

스트림 관련글

JAVA[자바] Stream 사용방법 2편(중간연산)
JAVA[자바] Stream 사용방법 3편(최종연산)

스트림이란?

자바8 에서 지원하는 기능이며 람다와 함께 사용이 가능하다. 스트림을 활용하면 더욱더 객체지향적인 코드를 작성할 수 있고, 코드가 간결해진다. 그리고 가독성이 높아진다.(물론 스트림을 모르는 사람에게는 가독성이 매우 별로다.)

하지만 성능적인 측면에서는 오히려 안좋을 수 있다. 실제로 코딩테스트에서 스트림을 사용하면 시간초과가 나는 경우가 있다. 또한 디버그하기가 매우 힘들다. 그러니 항상 스트림이 좋은건 아니니 목적에 맞게 잘 사용하는걸 권장한다.

스트림은 크게 3가지 과정으로 진행된다.

  1. 생성하기 : 스트림 인스턴스 생성
  2. 중간연산 : 원하는 결과값으로 만들기 위한연산(map, filter 등)
  3. 최종연산 : 원하는 형태의 결과값을 반환하기 위한 연산(인트형 반환, 리스트로 반환, 맵으로 반환 등)

생성 함수

실제 개발에서는 대부분 배열은 잘 사용하지않고, ArrayList 를 사용하는 경우가 많아서 컬렉션 스트림을 제외하고는 사용하는 경우가 적다. generate()iterate() 정도는 가끔씩 쓰인다.

배열 스트림

1
2
3
String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream1 = Arrays.stream(arr);
Stream<String> stream2 = Stream.of("a", "b", "c"); // 가변인자 사용

컬렉션 스트림

1
2
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

Stream.generate()

generate 사용시 Suplier<T> 함수형 인터페이스를 사용한다. 간단히 소개하자면 인자는 없으나 리턴값을 반환하는 함수이다. 주의사항으로 generate 는 값을 무한히 만들므로 limit 연산을 이용해 개수를 제한해줘야 한다.

1
2
Stream<String> generatedStream =
        Stream.generate(() -> "g").limit(3); // [g, g, g]

Stream.iterate()

iterate 사용시 특정 규칙이 있는 반복되는 값을 편하게 만들 수 있다. 주의사항으로 generate 와 같이 값을 무한히 만들므로 limit 연산을 이용해 개수를 제한해줘야 한다.

1
2
Stream<Integer> iteratedStream =
         Stream.iterate(30, n -> n + 2).limit(3); // [30, 32, 34]

기본타입 스트림

제네릭 타입을 사용하지 않고 직접 해당타입(int, long, double) 스트림을 생성할 수 있다. 대부분 범위 함수가 그렇듯 range(Inclusive, Exclusive) 이다. (시작값은 포함하나 마지막값은 포함하지 않는것) 하지만 rangeClosed(Inclusive, Inclusive) 를 이용하면 두 값을 포함할 수 있다.

1
2
IntStream intStream = IntStream.range(1, 5); // [1, 2, 3, 4]
LongStream longStream = LongStream.rangeClosed(1, 5); // [1, 2, 3, 4, 5]

문자열 스트림

Stringchar 의 ASCII 코드로 쪼갤 수 있다.

1
2
3
4
5
IntStream charsStream = 
  "Stream".chars(); // [83, 116, 114, 101, 97, 109]

IntStream charsStream =
    "Stream".codePoints(); // [83, 116, 114, 101, 97, 109]

병렬 스트림

Fork/Join framework 를 사용하여 쓰레드를 처리하는 병렬스트림으로 바꿀 수 있다.

1
2
3
4
5
6
Stream<Product> parallelStream = productList.parallelStream(); // 컬렉션
Arrays.stream(arr).parallel(); // 배열
IntStream intStream = IntStream.range(1, 150).parallel(); // 기본타입

// 되돌리기
IntStream intStream = intStream.sequential();

스트림 연결하기

1
2
3
4
Stream<String> stream1 = Stream.of("Java", "Scala", "Groovy");
Stream<String> stream2 = Stream.of("Python", "Go", "Swift");
Stream<String> concat = Stream.concat(stream1, stream2);
// [Java, Scala, Groovy, Python, Go, Swift]

Reference

https://futurecreator.github.io/2018/08/26/java-8-streams/

This post is licensed under CC BY 4.0 by the author.