모던 자바 인 액션 - chapter 1 자바 8 무슨 일이 일어나고 있는가
프로그래밍 분야는 빅데이터라는 도전에 직면하면서 멀티코어 컴퓨터나 컴퓨팅 클러스터를 이용해서 빅데이터를 효과적으로 처리할 필요성이 증가했다. 또한 병렬 프로세싱을 활용해야 하는데 이전의 자바로는 충분히 대응할 수 없었다. 자바 8부터 추가되는 기능은 현 시장에 요구하는 기능을 효과적으로 제공한다. 이 책은 자바 8에서 제공하는 기능의 모태인 세 가지 프로그래밍 개념을 상세히 설명한다.
세 가지 프로그래밍 개념
- 스트림 처리
- 스트림 API는 파이프라인(중간 연산이 연결되어 하나의 연산을 이루는 것)을 만드는데 필요한 많은 메서드를 제공한다. 또한 Thread를 사용하지 않으면서 병렬성을 손쉽게 얻을 수 있다.
- 동작 파라미터화로 메서드에 코드 정달하기
- 메서드를 파라미터화 해서 전달가능하다. 함수형 프로그래밍 기술을 활용한다.
- 병렬성과 공유 가변 데이터
- 병렬성을 손쉽게 얻을 수 있지만 포기해야 하는 점이 있다. 안전하게 실행할 수 있는 코드를 만드려면 공유된 가변 데이터에 접근하지 않아야 한다.
- 병렬성을 손쉽게 얻을 수 있지만 포기해야 하는 점이 있다. 안전하게 실행할 수 있는 코드를 만드려면 공유된 가변 데이터에 접근하지 않아야 한다.
자바 함수
프로그래밍 언어의 핵심은 값을 바꾸는 것이다. 프로그래밍 언어에서는 이렇게 변경할 수 있는 값을 일급(first class) 값이라고 부른다. 이전의 자바에서는 기본값, 인스턴스 만이 일급 값이었다. 메서드와 클래스는 일급 값이 아니었는데 런타임에 메서드를 전달할 수 있다면 프로그래밍에 유용하게 활용될 수 있다. 이에 자바 8부터는 메서드를 일급 값으로 바꿀 수 있는 기능을 추가했다.
메서드 참조
동작(메서드)의 전달을 위해 익명 클래스를 만들고 메서드를 구현해서 넘길 필요없이 준비된 함수를 메서드 참조를 통해서 전달할 수 있다. 아래 예제를 통해 자바 8에서는 더 이상 메서드가 이급 값이 아닌 일급 값인 것을 확인할 수 있다.
- 익명 클래스를 통한 파일 리스팅
File[] hiddenFiles = new File(".").listFiles(new FileFilter() { public boolean accept(File file) { return file.isHidden(); } });
- 메서드 참조를 이용한 파일 리스팅
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
람다(익명 함수)
자바 8에서는 메서드를 일급 값으로 취급할 뿐 아니라 람다를 포함하여 함수를 일급 값으로 취급할 수 있다.
스트림
이전 자바에서는 컬렉션 API를 사용한 for-each 문을 통하여 각 요소를 반복하면서 작업을 수행했다. 이러한 방식의 반복을 외부 반복이라 한다. 반면 스트림 API를 이용하면 루프를 신경 쓸 필요가 없다. 스트림 API에서는 라이브러리 내부에서 모든 데이터가 처리된다. 이와 같은 반복을 내부 반복이라 한다.
멀티스레딩
기존 Thread API로 멀티스레드 코드를 구현해서 병렬성을 이용하는 것은 쉽지 않다. 자바 스트림 API는 컬렉션을 처리하면서 발생하는 반복적인 코드 문제, 그리고 멀티코어 활용 어려움이라는 두 가지 문제를 모두 해결했다. 내부적으로 포크-조인 방식(일종의 분할정복)을 사용한다.
디폴트 메서드와 자바 모듈
기존 자바 기능으로는 진화하는 시스템의 인터페이스를 적절히 대응하기 어려웠다. 특히나 이미 사용되고 있는 인터페이스를 건드릴 경우 이를 구현하고 있는 모든 구현체가 변경되어야 했다. 자바 8에서는 디폴트 메서드를 이용해 기존 인터페이스를 구현하는 클래스를 바꾸지 않고도 인터페이스를 변경할 수 있다.
예를 들어 컬렉션 인터페이스는 이전에 stream 메서드를 지원하지 않았다. 하지만 자바 8에서 컬렉션 인터페이스에 디폴트 메서드로 stream 메서드를 추가하여 기존 인터페이스를 쉽게 변경할 수 있었다.
Optional 클래스
자바 8에서는 NPE(NullPointException)을 피할 수 있도록 도와주는 Optional<T> 클래스를 제공한다.