[Java 8 in Action] 52 ~ 61 요약
스트림 |
기존에는 컬렉션 API를 통해서 반복 과정을 직접처리하였습니다. (외부 반복)
반면 스트림 API를 이용하면 루프를 신겅 쓸 필요가 없습니다. 스트림 API에서는 라이브러리 내부에서 모든 데이터가 처리됩니다. (내부 반복)
컬렉션을 이용했을 때 다른 문제가 생길 수 있습니다. 예를 들어 많은 요소를 가진 목록을 반복한다면 오랜 시간이 걸릴 수 있습니다. 이럴 경우 멀티코어 컴퓨터를 통해 서로 다른 CPU 코어에 작업을 각각 할당해서 처리 시간을 줄일 수 있다면 좋을 것입니다.
멀티스레딩은 어렵다 |
이전 자바 버전에서 제공하는 스레드 API로 멀티스레딩 코드를 구현해서 병렬성을 이용하는 것은 어렵습니다.
멀티스레디 환경에서 각각의 스레드는 동시에 공유된 데이터에 접근하고, 데이터를 갱신할 수 있습니다. 이러한 스레드와 공유된 자원을 잘 관리하지 않으면 원하지 않은 결과가 나올 수 있습니다.
자바 8에서는 스트림 API로 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제 그리고 멀티코어 활용 어려움이라는 두 가지 문제를 모두 해결했습니다. 기존의 컬렉션에서는 데이터를 처리할 때 반복되는 패턴이 너무 많았습니다.
따라서 라이브러리에서 이러한 반복되는 패턴을 제공한다면 좋을 것이라는 아이디어가 동기가 되어,
필터링하거나 추출, 그룹화하는 등의 기능을 제공합니다.
큰 작업이 있을 때 다른 코어에게 각각 작업을 나눠줄 수 있는데 이 과정을 포킹 단계(forking step)이라고합니다. Divide and Merge
이러한 스트림 API와 컬렉션 API에는 차이점이 있는데
컬렉션은 어떻게 데이터를 저장하고 접근할지에 중점을 두는 반면
스트림은 데이터에 어떤 계산을 할 것인지 묘사하는 것에 중점을 둔다는 점입니다.
스트림은 스트림 내의 요소를 쉽게 병렬로 처리할 수 있는 환경을 제공한다는 것이 핵심입니다.
스트림은 병렬성을 얻기 위해 큰 스트림을 병렬로 처리할 수 있도록 라이브러리 단에서 작은 스트림으로 분할합니다.
또한 filter가은 메서드로 전달된 메서드가 상호작용을 하지 않는다면 가변 공유 객체를 통해 공짜로 병렬성을 누릴 수 있습니다.
상호작용을 하지 않는다는 것이 누구와 상호작용을 뜻하는 것이며 가변 공유 객체를 통해 병렬성을 누릴 수 있다하는데
이는 가변 공유 객체에 직접적인 변화를 주지 않아 가변 공유 객체를 사용하는 것이 자유롭고 그로인해 병렬적으로 처리해도 부담되는 부분이 없다는 의미로 해석하면 될까 생각이 들었습니다.
자바의 이러한 변화과정에서 있었던 가장 어려웠던 부분 중 하나는 인터페이스의 변경입니다. 인터페이스를 업데이트하려면 해당 인터페이스를 구현하는 모든 클래스도 업데이트 해야했기에 불가능에 가까워습니다. 이는 디폴트 메서드를 통해 해결할 수 있었습니다.
디폴트 메서드 |
자바 8에서는 라이브러리설계자가 더 쉽게 변화할 수 있는 인터페이스를 만들 수 있도록 디폴트 메서드를 추가했습니다.
프로그래머가 직접 디폴트 메서드를 구현하는 상황은 흔치 않습니다. 이는 미래에 프로그램이 쉽게 변화할 수 있는 환경을 제공하는 기능이기 때문입니다. 덕분에 구현 클래스에서 구현하지 않아도 되는 메서드를 인터페이스가 포함할 수 있는 기능으로도 사용됩니다. 인터페이스 규격명세에 default라는 새로운 키워드를 지원합니다.
하나의 클래스에는 여러 인터페이스를 구현할 수 있습니다. 그리고 다중 디폴트 메서드가 존재할 수 있는데 이것은 다중 상속을 의미하게 되는 것입니다. C++에서 나타나는 다이아몬드 상속 문제를 피해야하는데 이는 뒷장에서 나온다고합니다.
함수형 프로그램에서 가져온 다른 유용한 아이디어 |
함수형 언어에는 명시적으로 데이터 형식을 설명하도록 유도하여 null을 회피하는 기법이 있는데
자바 8에서는 Optional<T>이라는 클래스를 통해 값을 갖거나 갖지 않을 수 있는 컨테이너 객체 입니다.
값이 없는 상황에 어떻게 처리할 지 명시적으로 구현하는 메서드를 포함하여있습니다. 그렇기에 NullPointer 예외를
피할 수 있습니다.
그리고 구조적 패턴 매칭 기법도 있습니다.
자바에서는 if - then - else나 switch 문을 통하여 사용했다면 다른 언어에서는 패턴 매칭으로 더 정확한 비교를 구현하엿습니다. 자바 8에서는 패턴 매칭 기법을 완벽하게 지원하지 않습니다.
패턴 매칭에 대해서는 뒤에 더 자세히 나오며 지금은 패턴 매칭이 switch를 확장한 것으로 데이터 형식 분류와 분석을 한 번에 수행할 수 있다는 정도로만 생각하면 되겠습니다.
요약 |
언어 생태계의 모든 언어는 변화를 통해 살아남거나 탈락합니다. 자바도 모릅니다.
자바 8은 더 효과적이고 간결하게 구현할 수 있는 기능을 제공합니다.
기존 자바는 멀티 프로세싱을 온전히 활용하기 어렵습니다.
자바 8에서 함수는 일급값이며 메서드를 함수형값으로 넘겨주는 방법과 익명 함수 구현 방법을 기억합시다.
자바 8의 스트림 개념 중 일부는 컬렉션에서 가져왔으며 스트림과 컬렉션을 적절하게 활용한다면 스트림의 인수를 병렬로 처리할 수 있으며 더 가독성이 좋은 코드를 구현할 수 있습니다.
인터페이스에서 디폴트 메서드를 이용하면 메서드 바디를 제공할 수 있으므로 인터페이스를 구현하는 다른 클래스에서
해당 메서드를 구현하지 않아도 됩니다.
함수형 프로그래밍에서 null 처리 방법과 패턴 매칭 활용 등 흥미로운 기법을 발견할 수 있었습니다.
긴 글 읽어주셔서 감사합니다.
부족한 점이 있다면 부디 알려주시면 감사하겠습니다.