티스토리 뷰
Chapter 1 - 자바 8, 9, 10, 11 : 무슨 일이 일어나고 있는가
1.1 역사의 흐름은 무엇인가?
자바 역사를 통틀어 가장 큰 변화가 자바 8에서 일어났다.
- 고전적 정렬 방식
Collections.sort(inventory, new Comprator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
- 자바 8에서의 간단한 구현 방식
inventory.sort(comparing(Apple::getWeight));
조금 더 자연어에 가깝게 코드 구현이 가능하다.
멀티코어 CPU 대중화와 같은 하드웨어적인 변화도 자바 8에 영향을 줬다.
자바 8 등장 이전에는 나머지 코어를 활용하려면 스레드를 사용하는 것이 좋다는게 정론 But 스레드는 관리가 어렵고 많은 문제를 야기시키는 단점이 있음
-> 자바는 이러한 병렬 실행 환경을 쉽게 관리할 수 있도록 진화하려 노력함
자바 8에서는 병렬 실행 환경을 위한 새로운 기법을 제안
자바 8에서 제공하는 새로운 기술
- 스트림 API
- 매서드에서 코드를 전달하는 기법
- 인터페이스의 디폴트 매서드
스트림 API는 병렬 연산을 지원하는 자바8에서의 새로운 API로 항상 최적의 저수준 실행 방법을 선택한다. 스트림을 이용하면 상대적으로 문제가 많았던 syncronized를 사용할 필요가 없다.
자바 8 에서는 스트림 API 덕분에 매서드에 코드를 전달하는 간결기법(매서드 참조와 람다)과 인터페이스의 디폴트 매서드가 존재할 수 있다.
매서드를 코드에 전달하는 기법은 함수형 프로그래밍에서 위력을 발휘한다.
1.2 왜 아직도 자바는 변화하는가?
자바는 처음부터 많은 유용한 라이브러리를 포함하는 잘 설계된 객체지향 언어로 시작했다. 코드를 JVM 바이트 코드로 컴파일하는 특징 때문에 자바는 인터넷 애플릿 프로그램의 주요 언어가 되었다.
JVM의 업데이트 덕에 JVM에서 실행되는 경쟁 언어는 더욱 부드럽게 실행될 수 있으며, 자바와 상호 동작할 수 있게 되었다. 또한 자바는 다양한 임베디드 컴퓨팅 분야도 장악하고 있다.
하지만 프로그래밍 언어 생태계에 변화의 바람이 불었다. 프로그래머는 빅데이터라는 도전에 직면하면서 멀티코어 컴퓨터나 컴퓨팅 클러스터를 이용해서 빅 데이터를 효과적으로 처리할 필요성이 커졌다. 또한 병렬 프로세싱을 활용해야 하는데 이전의 자바로는 충분히 대응할 수 없었다.
자바 8은 더 다양한 프로그래밍 도구 그리고 다양한 프로그래밍 문제를 더 빠르고 정확하며 쉽게 유지 보수할 수 있다는 장점을 제공한다.
자바 8에 추가된 기능은 자바에 없던 완전히 새로운 개념이지만 현 시장에 요구하는 기능을 효과적으로 제공한다. 이 책은 자바 8에서 제공하는 기능의 모태인 세 가지 프로그래밍 개념을 자세히 설명한다.
스트림 처리
자바 8에서는 java.util.stream 패키지에 스트림 API가 추가 되었다. 기존에는 한 번에 한 항목을 처리 했지만, 이 작업들을 고수준으로 추상화해서 일련의 스틀미을 만들어 처리할 수 있게 했다. 또한 스레드라는 복잡한 작업을 사용하지 않으면서도 병렬성을 ?공짜로? 얻을 수 있다.
동작 파라미터로 매서드에 코드 전달하기
자바 8에서는 매서드(우리 코드)를 다른 매서드의 인수로 넘겨주는 기능을 제공한다. 이러한 기능을 이론적으로 동작 파라미터화라고 부른다.
왜 중요하냐? 스트림 API가 연산 동작을 파라미터화 할 수 있는 코드를 전달한다는 사상에 기초하기 때문이다.
병렬성과 공유 가변 데이터
세상에 공짜는 없는데 앞서, 병렬성을 공짜로 얻을 수 있다고 했다. 병렬성을 얻기 위해 스트림 매서드로 전달하는 코드의 동작 방식이 조금 바뀌었다.(아직 안나옴)
스트림 매서드로 전달하는 코드는 다른 코드와 동시에 실행하더라도 안전하게 실행 될 수있게 하기 위해서, 순수(pure) 함수, 부작용 없는(side-effect-free) 함수, 상태 없는(stateless) 함수들이 등장하는데 추후 자세히 소개한다...
결론은 syncronized 쓰지 말자 이다.
자바가 진화해야하는 이유
고전적인 객체 지향에서 벗어나 함수형 프로그래밍으로 다가 섰다는 것이 자바 8에서의 가장 큰 변화다.
1.3 자바 함수
자바 8에서는 함수를 ㅅ ㅐ로운 값의 형식으로 추가했다.
병렬 프로그래밍을 활용할 수 있는 스트림과 연계될 수 있도록 함수(매서드)를 만들었기 때문이다. 함수를 값처럼 취급해서 런타임에 매서드의 파라미터로 사용할 수 있도록 하는 것 이게 자바 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에서는 (int x) -> x+1, 즉 x라는 인수를 호출하면 x+1을 반환하는 동작을 수행하도록 하는 코드를 파라미터로 넘길 수 있다.
왜 동작을 매서드로 만들어서 넘겨주지 않느냐? 라고 물을 수 있으나 재사용성이 떨어지는 코드를 매서드로 만드는 것도 귀찮은 일이기 때문이다.
1.4 스트림
스트림 API를 이용하면 컬렉션 API와는 상당히 다른 방식으로 데이터를 처리할 수 있다.
컬렉션 API를 사용하 for-each 루프를 이용하여 각 요소를 반복하면서 작업을 수행했다. 이러한 방식의 반복을 외부 반복(external iteration)이라 한다.
반면 스트림 API를 이용하면 루프를 신경 쓸 필요가 없다. 스트림 API에서는 라이브러리 내부에서 모든 데이터가 처리된다. 이와 같은 반복을 내부 반복(internal iteration)이라고 한다.
또, 컬렉션 API 을 썼을 때 거대한 리스트 처리를 병렬 처리하기 어렵지만 스트림 API는 멀티스레딩을 편하게 구현할 수 있다.
멀티스레딩은 어렵다.
계속해서 이야기 하지만 자바 8에서 스트림 PAI는 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드문제 그리고 멀티코어의 활용 어려움 이 두가지 문제를 모두 해결했다.
특히, 자주 반복되는 패턴을 라이브러리에서 제공하는데 데이터 필터링, 데이터 추ㄹ출 데이터 그룹화 등의 기능을 별도의 매서드로 제공한다.
컬렉션을 가장 빠르게 필터링할 수 있는 방법이 우습게 들리겠지만,
컬렉션 -> 스트림 -> 필터링(병렬처리) -> 컬렉션 복원
이런 식으로 처리하는 게 낫다.
순차처리 스트림은 .stream() , 병렬 처리 스트림은 .parallelStream()을 사용한다.
1.5 디폴트 매서드와 자바 모듈
구현 클래스에서 구현 하지 않ㄴ아도 되는 매서드를 인터에피스에 추가할 수 잇는 기능을 제공한다.
기존 코드를 건드리지 안호도 원래의 인터페이스 설계를 자유롭게 확장할 수 있음
default라는 새로운 키워드를 지원한다.
예를들어, 자바 8에서는 List에 직접 sort 매서드를 호출할 수 있따. List 인터페이스에 디폴트 매서드 정의가 추가 되었기 때문이다.
default void sort(Comparator<? super E> c) {
Collections.sort(this, c);
}
1.6 함수형 프로그래밍에서 가져온 다른 유용한 아이디어
- NPE를 피하기 위해서 Optinal 클래스가 나왔음
- 정규표현식 같은 구조적 패턴 매칭 기법도 추가됨
마치며
1장을 정리해봤는데, 정리하면서 읽는게 내용을 이해하는데는 도움이 됐으나 너무 오래걸린다. 앞으로 계속 할지 모르겠음
'개발 > JAVA' 카테고리의 다른 글
[JAVA] Json 형태의 String에 Json Pretty Format 적용하기 (1) | 2023.02.07 |
---|---|
모던 자바 인 액션(Modern Java in Action). 2장 요약 (0) | 2023.01.31 |
[Java] 리스트 객체 내 중복 제거(List to Set) (0) | 2023.01.26 |
[JAVA] 이중콜론(::) 표현식 (0) | 2023.01.26 |
[JAVA] Optional 클래스 (1) | 2023.01.26 |
- Total
- Today
- Yesterday
- 오블완
- CloudFront
- Kotlin
- serverless
- openAI API
- Log
- 스프링부트
- MySQL
- Elastic cloud
- ChatGPT
- AWS
- elasticsearch
- OpenFeign
- java
- cache
- JWT
- Spring
- 후쿠오카
- lambda
- S3
- GIT
- OpenAI
- 람다
- docker
- springboot
- AWS EC2
- terraform
- AOP
- 티스토리챌린지
- EKS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |