많은 수의 데이터를 다룰 때, 컬렉션이나 배열에 데이터를 담고 원하는 결과를 얻기 위해 for문과 Iterator를 이용해서 코드를 작성해왔다. 이런 방법은 코드도 길고 알아보기도 어렵다. 또한 재사용성도 떨어진다.
이러한 문제점들을 해결하기 위해 만들어진 '스트림'에 대해 알아보자!
▷ 스트림의 특징
○ 스트림은 데이터 소스를 변경하지 않는다.
→ 스트림은 데이터 소스로부터 데이터를 읽기만 할 뿐, 데이터 소스를 변경하지 않는다는 차이가 있다. 필요하다면 정렬된 결과를 컬렉션이나 배열에 담아서 반환할 수 있다.
○ 스트림은 일회용이다.
→ 스트림은 Iterator처럼 일회용이다. 그렇기 때문에 한 번 사용하면 다시 사용할 수 없다. 필요하다면 스트림을 재생성해야 한다.
○ 스트림은 작업을 내부 반복으로 처리한다.
→ 내부 반복이라는 것은 반복문을 메서드의 내부에 숨길 수 있다는 것을 의미한다. forEach()는 스트림에 정의된 메서드 중의 하나로 매개변수에 대입된 람다식을 데이터 소스의 모든 요소에 적용한다.
○ 지연된 연산
→ 스트림 연산에서 중요한 점은 최종 연산이 수행되기 전까지 중간 연산이 수행되지 않는다는 것이다. 즉. distinct()나 sort() 같은 중간 연산을 호출해도 즉각적인 연산이 수행되는 것은 아니라는 것이다. 중간 연산은 어떤 작업이 수행되어하는지 지정해주는 것뿐이다. 최종 연산이 수행되어야 비로소 중간 연산을 거쳐 최종 연산에서 소모된다.
○ Stream<Integer>와 IntStream
→ 기본적으로 Stream<T>이지만, 데이터 소스의 요소를 기본형으로 다루는 스트림, IntStream, LongStream, DoubleStream이 제공된다. 일반적으로 Stream<Integer> 대신 IntStream을 사용하는 것이 더 효율적이고, IntStream에는 int타입의 값으로 작업하는데 유용한 메서드들이 포함되어있다.
▷ 스트림 만들기
아래의 다양한 소스들로부터 스트림을 생성할 수 있다.
- 컬렉션
- 배열
- 특정 범위의 정수
- 임의의 수
- 람다식
- 파일
- 빈 스트림
- 컬렉션에서 스트림 생성
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream();
intStream.forEach(System.out::println);
- 배열에서 스트림 생성
String[] strArr = {"하나","둘","셋","넷","다섯"};
Stream<String> strStream = Arrays.stream(strArr);
strStream.forEach(System.out::println);
- 특정 범위의 정수에서 스트림 생성
IntStream intStream1 = IntStream.range(1,5); // 1,2,3,4
IntStream intStream2 = IntStream.rangeClosed(1,5); // 1,2,3,4,5
- 임의의 수에서 스트림 생성
1. limit() 사용 O
IntStream intStream3 = new Random().ints(); // 무한 스트림
intStream3.limit(5).forEach(System.out::println); // 5개 요소만 출력
2. limit() 사용 X
IntStream intStream4 = new Random().ints(5);
- 람다식에서 스트림 생성
1. iterate() -> 이전 결과를 이용해서 다음 요소를 계산함.
Stream<Integer> evenStream = Stream.iterate(0, n -> n + 2); // 0,2,4,6, ...
2. generate() -> 이전 결과를 이용해서 다음 요소를 계산하지 않음.
Stream<Double> randomStream = Stream.generate(Math::random);
Stream<Integer> oneStream = Stream.generate(() -> 1);
- 파일에서 스트림 생성
Stream<Path> fileStream = Files.lines(Path dir);
- 빈 스트림 생성
Stream emptyStream = Stream.empty(); // 빈 스트림 생성해서 반환
long count = emptyStream.count(); // count의 값은 0
- 두 스트림의 연결
String[] str1 = {"123","456","789"};
String[] str2 = {"abc","def","ghi"};
Stream<String> strs1 = Stream.of(str1);
Stream<String> strs2 = Stream.of(str2);
Stream<String> strs3 = Stream.concat(strs1,strs2);
'Language > Java' 카테고리의 다른 글
[Java]스트림(stream)(3/3) (0) | 2022.06.09 |
---|---|
[Java]스트림(stream)(2/3) (0) | 2022.06.07 |
[Java] 람다식 (0) | 2022.06.06 |
예외처리(Exception Handling) (0) | 2022.05.27 |
객체 지향 프로그래밍에 대해 묻는다면 ? (0) | 2022.05.25 |