
JDK 1.8(8버전)부터 제공된 컬렉션 혹은 배열에 저장된 요소를 하나씩 참조하여 람다 표현식으로 처리할 수 있는 반복자이다. 스트림이 존재하기 이전에는 Iterator 인터페이스를 사용했다고 한다.
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
Iterator iterator = numbers.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
Stream<Integer> stream = numbers.stream();
stream.forEach(number -> System.out.println(number));
int[] arr = {1,2,3,4,5};
Arrays.stream(arr).forEach(n -> System.out.print(n)); //12345
int sum = Arrays.stream(arr).sum(); //sum = 15
List<Customer> cList = new ArrayList<>();
cList.add(new Customer("Lee", 10)); //name, age
cList.add(new Customer("Kim", 15));
cList.add(new Customer("Hong", 13));
System.out.println(cList.stream().mapToInt(c -> c.getAge()).sum()); //mapToInt 대신 map을쓰면 Integer(Wrapper)타입으로 반환하기 때문에 sum()작동 안됨
cList.stream().filter(c->c.getAge()>=12).filter(c->c.getAge()>=13).map(c->c.getName()).sorted().forEach(s->System.out.println(s)); //filter,map,sort,forEach 순서갖 중요
Stream의 요소들을 하나의 데이터로 만든다.
String[] greetings = {"안녕하세요~", "hello", "Good morning"};
System.out.println(Arrays.stream(greetings).reduce("", (s1,s2)->{
if(s1.length() >= s2.length()) return s1;
else return s2;
})); //Good morning 출력
🔼동작 과정
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Optional<Integer> sum = numbers.reduce((x, y) -> x + y);
sum.ifPresent(s -> System.out.println("sum: " + s)); //55출력
🔼동작 과정
람다 표현식
스트림은 람다식으로 요소 처리 코드를 제공한다. 스트림이 제공하는 대부분의 요소 처리 메소드는 함수형 인터페이스를 사용하므로, 람다식으로 요소 처리 코드를 제공할 수 있다.
(람다식은 함수형 객체로 final로 선언된 변수만 읽을 수 있기 때문에, 본 객체(데이터)에 어떤 영향도 끼치지 않는다.)
생성, 중간처리, 최종처리
후술하겠지만, 스트림의 처리는 생성, 중간처리, 최종처리 3단계로 구분된다.
재사용 불가능
스트림은 생성되고, 중간처리를 거쳐 최종처리까지 완료되면 닫히게된다. 이미 닫힌 스트림은 재사용할 수 없으며, 재사용을 시도할 경우 예외가 발생한다. 즉 스트림은 일회용이다.
continue, break 불가능
스트림은 continue, break가 불가능하므로, 중간에 break를 사용하는 조건문이 있다면, 스트림 대신 for문을 사용하는 것이 좋다. 예를 들어, 10번의 루프를 돌 때, for문에서는 5번만 반복 후 break하는 조건문을 만들 수 있지만, 스트림에서는 10번 모두 돌아야 하므로 오버헤드가 발생할 수 있다.
primitive type(int)형, 그리고 데이터에 대한 접근만 한다 했을 경우, for문 보다 Stream이 두배 가량 빠르다
하지만 Wrapper(Integer)과 같은 데이터를 놓고 본다면 for문과 Stream의 성능 차이는 거의 없다.
즉, primitive type(int)형은 JVM에서 Stack영역에 저장되어 직접 참조로 속도가 빠르지만, Wrapper(Integer)과 같은 데이터는 heap영역에 저장되기에 간접 참조가 일어나 속도가 다른것 입니다.
참고 : 스트림은 언제나 좋을까?
좋은 정보 얻어갑니다, 감사합니다.