자바는 처음부터 많은 유용한 라이브러리를 포함하는 잘 설계된 객체지향 언어로 시작했다.
코드를 JVM 바이트 코드로 컴파일하는 특징 때문에 자바는 인터넷 애플리케이션의 주요 언어가 되었다.
JVM의 업데이트 덕에 JVM에서 실행되는 경쟁 언어는 더욱 부드럽게 실행될 수 있으며, 자바와 상호 동작할 수 있게 되었다.
또한 자바는 다양한 임베디드 컴퓨팅 분야도 장악하고 있었다.
하지만 프로그래밍 언어 생태계에 변화의 바람이 불었다.
프로그래머는 빅데이터라는 도전에 직면하면서 멀티코어 컴퓨터나 컴퓨팅 클러스터를 이용해서 빅 데이터를 효과적으로 처리할 필요성이 커졌다. 또한 병렬 프로세싱을 활용해야 하는데 이전의 자바로는 충분히 대응할 수 없었다.
그렇기에 자바는 변화하였다.
자바 8은 다양한 프로그래밍 도구와 프로그래밍 문제를 더 빠르고 정확하며 쉽게 유지 보수할 수 있다는 장점을 제공한다.
자바 8에 추가된 기능은 자바에 없던 완전히 새로운 개념이지만 현 시장에 요구하는 기능을 효과적으로 제공한다.
이 책은 자바 8에서 제공하는 기능의 모태인 세 가지 프로그래밍 개념을 자세히 설명한다.
📕 세 가지 프로그래밍 개념
📗 스트림 처리
조립라인 처럼 스트림 API는 파이프라인을 만드는 데 필요한 많은 메서드를 제공한다.
또한 스레드라는 복잡한 작업을 사용하지 않으면서 공짜로 병렬성을 얻을 수 있다.
📗 동작 파라미터화(behavior parameterization)로 메서드에 코드 전달하기
동작(메서드)을 파라미터화 해서 전달 가능하다.
함수형 프로그래밍 기술을 이용한다.
📗 병렬성과 공유 가변 데이터
병렬성을 공짜로 얻을 수 있지만 이를 얻기 위해 포기해야 하는 점이 있다.
안전하게 실행할 수 있는 코드를 만들려면 공유된 가변 데이터(shared mutable data)에 접근하지 않아야 한다.
📕 자바 함수
자바 8에서 함수 사용법은 일반적인 프로그래밍 언어의 함수 사용법과 아주 비슷하다.
프로그래밍 언어의 핵심은 값을 바꾸는 것이다.
전통적으로 프로그래밍 언어에서는 이 값을 일급(first-class) 값(또는 시민)이라고 부른다.
이전까지 자바 프로그래밍 언어에서는 기본값, 인스턴스만이 일급 시민이었다.
메서드와, 클래스는 이 당시 일급 시민이 아니었는데, 런타임에 메서드를 전달할 수 있다면,
즉 메서드를 일급 시민으로 만들면 프로그래밍에 유용하게 활용될 수 있다.
자바 8 설계자들은 이급 시민을 일급 시민으로 바꿀 수 있는 기능을 추가했다.
📗 메서드 참조 (method reference)
동작의 전달을 위해 익명 클래스를 만들고 메서드를 구현해서 넘길 필요 없이, 준비된 함수를 메서드 참조 ::를 이용해서 전달할 수 있다.
아래 예제를 통해 자바 8에서는 더 이상 메서드가 이급값이 아닌 일급값인것을 확인할 수 있다.
[익명 클래스를 통한 파일 리스팅]
File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isHidden();
}
});
[메서드 참조를 이용한 파일 리스팅]
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
📗 람다 (익명 함수)
자바 8에서는 (기명 named)메서드를 일급값으로 취급할 뿐 아니라 람다(anonymous function)를 포함하여 함수도 값으로 취급할 수 있다.
📕 스트림
스트림 API 이전 컬렉션 API를 이용하여 다양한 로직을 처리하였을 것이다.
스트림 API를 이용하면 컬렉션 API와는 상당히 다른 방식으로 데이터를 처리할 수 있다.
컬렉션 API를 사용하면 for-each 루프를 이용하여 각 요소를 반복하면서 작업을 수행했다.
이러한 방식의 반복을 외부 반복(external iteration)이라 한다.
반면 스트림 API를 이용하면 루프를 신경 쓸 필요가 없다.
스트림 API에서는 라이브러리 내부에서 모든 데이터가 처리된다.
이와 같은 반복을 내부 반복(internal iteration)이라고 한다.
📗 멀티스레딩
기존 스레드 API로 멀티스레딩 코드를 구현해서 병렬성을 이용하는것은 쉽지 않다.
자바 스트림 API는 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제, 그리고 멀티코어 활용 어려움이라는 두 가지 문제를 모두 해결했다.
내부적으로 fork-join 방식을 사용한다.
📕 디폴트 메서드와 자바 모듈
기존 자바 기능으로는 대규모 컴포넌트 기반 프로그래밍 그리고 진화하는 시스템의 인터페이스를 적절히 대응하기 어려웠다.
자바 8에서 지원하는 디폴트 메서드를 이용해 기존 인터페이스를 구현하는 클래스를 바꾸지 않고도 인터페이스를 변경할 수 있다.
예를 들어 List/나 Collection/ 인터페이스는 이전에 stream이나 parallelStream 메서드를 지원하지 않았다.
하지만 자바 8에서 Collection 인터페이스에 stream메서드를 추가하고 이를 디폴트 메서드로 제공하여
기존 인터페이스를 쉽게 변경할 수 있었다.
📕 함수형 프로그래밍에서 가져온 다른 유용한 아이디어
자바 8에서는 NPE(NullPointerException)을 피할 수 있도록 도와주는 Optional<T> 클래스를 제공한다.