Open beginin15 opened 3 years ago
아래는 원본에서 일부만 가져왔습니다. 저의 추측도 포함되어 있기 때문에 정확하지 않은 내용이 있을 수 있다는 점! 참고해주세요. 참고로 가독성은 원본이 더 나은 것 같습니다.ㅋㅋ
(p.10) '스트림이 처리하는 데이터(심지어 처리된 데이터)를 모두 메모리에 저장하지 않을 수도 있도록 설계되었다. 따라서 스트림을 이용하면 컴퓨터 메모리에 저장할 수 없는 큰 데이터도 문제없이 처리할 수 있다.'
- 자바의 스트림 API가 빅데이터를 다루기 좋은 이유는 속도가 아니라 메모리 측면에서 다뤄진다.
- 스트림은 요소들을 메모리에 저장하지 않는다. (반면 컬렉션은 모든 요소를 메모리에 저장한다.)
- 스트림은 Source(컬렉션, 배열, 입출력 채널 등)로부터 입력받은 데이터를 처리하여 Destination으로 전달하는 파이프라인의 일종이다.
![https://miro.medium.com/max/700/1*PAC0g5wHAaYILcUepKStRQ.gif](https://miro.medium.com/max/700/1*PAC0g5wHAaYILcUepKStRQ.gif)
출처 - [https://medium.com/elevate-java/java-streams-an-in-memory-data-structure-d6984eea1091](https://medium.com/elevate-java/java-streams-an-in-memory-data-structure-d6984eea1091)
그렇다고 아예 메모리를 사용하지 않는 것은 아니고 중간 연산을 처리하는 과정에서 RAM은 사용하지 않을까? 단지 그 크기가 전체가 아닌 chunk 수준으로 필요하기 때문에 빅데이터를 다루기엔 문제가 없는 것이 아닌지.
스트림 API는 중간 연산과 최종 연산으로 분류할 수 있다.
최종 연산이 호출되기 전까지 중간 연산은 수행되지 않는다.
최종 연산의 내용에 따라 중간 연산을 모든 데이터에 수행하지 않을 수 있다. 모든 데이터가 아니라 필요한 만큼의 데이터에만 중간 연산을 수행하기도 한다는 의미이다.
Integer integer = Arrays.asList(10,3,13,4,1,52)
.stream()
.filter(number -> number % 2 == 0)
.findFirst()
.get();
최종 연산이 findFirst()
이기 때문에 10, 3, 13, 4, 1, 52
에 대해 filter
연산(중간 연산)을 수행하지 않는다. 첫 번째 요소인 10
에만 filter
를 수행하고 그 결과를 반환한다.
이러한 특징은 스트림의 병렬 처리와 더불어 자동으로 최적화하는 효과를 누릴 수 있게 해준다.
원래는 하나의 코어에서 하나의 스레드를 처리했지만 하이퍼스레딩 기술이 생겨나면서 코어보다 스레드가 많은 상황이 존재한다.
하이퍼스레딩 기술이란 하나의 코어가 둘 이상의 스레드를 실행할 수 있는 기술이다.
프로그래머가 문제없이 스레드를 직접 관리하는 것은 어렵다. 오죽 어려우면 자바의 버전이 높아질 때마다 꾸준하게 스레드를 안전하게 사용하기 위한 장치들을 지원했을까!
장점
단점
스트림은 함수 객체나 람다를 이용하기 때문에 그 특성으로 인한 제약이 발생할 수 있다.
함수 객체나 람다는 지역 변수, 멤버 변수에 접근하여 수정할 수 없다. (final
변수 읽기만 가능)
반복문에서 조건과 함께 사용하는 return
, break
, continue
와 같은 동작을 구현할 수 없다.
스트림이 함수 객체와 람다를 사용하는 이유는 안정적인 병렬 작업을 위해 side-effect가 없는 순수 함수를 사용하는 것과 관련이 있다. 이는 추후에 더 자세히 알아보자.
스트림의 단점과 사용 시 주의해야 할 점은 나중에 더 자세히 살펴봐야 할 것 같다.
기본적으로 스트림 개념 중 일부는 컬렉션에서 가져왔으며 쿼리와 같은 데이터 추상화 아이디어를 더한 것 같다.
유틸성 클래스는 상태를 가지고 있지 않는 경우가 많기 때문에 메서드 참조 방식으로 활용되기에 적합하다.
공유된 가변 데이터에 접근하지 않아 부작용(side-effect)를 발생시키지 않는 함수
여기서 부작용(side-effect)란, 함수의 실행으로 인해 함수 외부가 영향을 받는 것을 의미한다.
default
라는 새로운 키워드를 지원한다.HttpClient
) 제공출처 - https://en.wikipedia.org/wiki/Multiple_inheritance
다중 상속을 허용하면 발생할 수 있는 문제
동일한 시그니처를 갖는 메소드가 2개 이상의 부모 클래스에서 오버라이드된 경우, 컴파일러는 어떤 부모의 메소드를 호출해야할지 모호하다.
class GrandParent {
void method(){
System.out.println("GrandParent");
}
}
class ParentA extends GrandParent {
@Override
void method(){
System.out.println("ParentA");
}
}
class ParentB extends GrandParent {
@Override
void method(){
System.out.println("ParentB");
}
}
class Child extends ParentA, ParentB {
@Override
void method() {
super.method(); //ParentA의 메소드를 호출해야하나? ParentB의 메소드를 호출해야하나?
}
}
C / C++은 다중 상속이 가능하며 위와 같은 문제를 개발자에게 맡겨 놓았다. 반면 자바는 다중 상속을 막아놓았다.
그러나 자바에서 인터페이스는 다중 상속이 가능하다. 인터페이스의 default
메소드로 인해 다중 디폴트 메서드가 존재할 수 있다. 동일한 시그니처를 갖는 default
메소드가 2개 이상의 부모에 존재하는 경우, 컴파일 에러가 발생한다.
스트림 API는 빅데이터를 다루기에 적합하다?
Lazy evaluation
프로세서 - 코어 / 프로세스 - 스레드 관계
스트림 API
참고 자료