[JAVA]자바 Stream 사용방법 1편(생성하기)
스트림 관련글
JAVA[자바] Stream 사용방법 2편(중간연산)
JAVA[자바] Stream 사용방법 3편(최종연산)
스트림이란?
자바8 에서 지원하는 기능이며 람다와 함께 사용이 가능하다. 스트림을 활용하면 더욱더 객체지향적인 코드를 작성할 수 있고, 코드가 간결해진다. 그리고 가독성이 높아진다.(물론 스트림을 모르는 사람에게는 가독성이 매우 별로다.)
하지만 성능적인 측면에서는 오히려 안좋을 수 있다. 실제로 코딩테스트에서 스트림을 사용하면 시간초과가 나는 경우가 있다. 또한 디버그하기가 매우 힘들다. 그러니 항상 스트림이 좋은건 아니니 목적에 맞게 잘 사용하는걸 권장한다.
스트림은 크게 3가지 과정으로 진행된다.
- 생성하기 : 스트림 인스턴스 생성
- 중간연산 : 원하는 결과값으로 만들기 위한연산(map, filter 등)
- 최종연산 : 원하는 형태의 결과값을 반환하기 위한 연산(인트형 반환, 리스트로 반환, 맵으로 반환 등)
생성 함수
실제 개발에서는 대부분 배열은 잘 사용하지않고, 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]
문자열 스트림
String
을 char
의 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]