Java/Effective Java(7)
-
[아이템 48] 스트림 병렬화는 주의해서 사용하라
동시성 프로그래밍 동시성 프로그래밍을 할때는 항상 안전성(safety)와 응답 가능(liveness) 상태를 유지해야 하는 것에 주의해야 한다. 동시성 프로그래밍 주의점 예제) 메르센 소수를 생성하는 프로그램 parallel() 사용 ⇒ 프로그램은 아무것도 출력하지 못하면서 CPU는 90%나 잡아먹는 상태 나타남 스트림 라이브러리가 이 파이프라인을 병렬화하는 방법을 찾아내지 못했기 때문이다. 아래의 코드의 경우, 새롭게 메르센 소수를 찾을 때마다 그 전 소수를 찾을 때 보다 두배 정도 더 오래 걸린다. 원소 하나를 계산하는 비용이 대략 그 이전까지의 원소 전부를 계산한 비용을 합친 것만큼 든다는 뜻 public static void main(String[] args) { primes() .parallel..
2023.05.31 -
[아이템 47] 반환 타입으로는 스트림보다 컬렉션이 낫다
서론 자바 7 까지는 일련의 원소를 반환하는 메서드의 반환 티입으로 컬렉션 인터페이스나 Iterable, 배열을 써왔다. 기본은 컬렉션 인터페이스이며, for-each 문에서만 쓰이거나 반환된 원소 시퀀스가 일부 Collection 메서드를 구현할 수 없을 때(주로 contains(Object) 같은)는 Iterable 인터페이스를 썼다. 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 배열을 썼다. 자바 8의 스트림 도입 후 선택이 복잡해졌다. Stream Iterable 인터페이스가 정의한 추상 메서드를 전부 포함할 뿐만 아니라, Iterable 인터페이스가 정의한 방식대로 동작한다. 하지만 for-each 로 스트림을 반복할 수 없는 이유는 Iterable 을 확장(extends)하지 않아서..
2023.05.31 -
[아이템 46] 스트림에서는 부작용 없는 함수를 사용하라
스트림 패러다임 스트림 패러다임의 핵심은 계산을 일련의 변환으로 재구성하는 부분이다 이때 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수이다. 순수 함수란 오직 입력만이 결과에 영향을 주는 함수를 말한다. 다른 가변상태 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다. 스트림 연산에 건네는 함수 객체는 모두 부작용(side effect)가 없어야 한다. 예제) 텍스트 파일에서 단어별 수를 세어 빈도표를 생성하는 코드 // 스트림 API를 적절히 사용하지 못하는 코드 public static void main(String[] args) { Map freq = new HashMap(); try (Stream words = new Scanner("file").tokens())..
2023.05.30 -
[아이템 45] 스트림은 주의해서 사용하라
스트림 API 스트림 API는 다량의 데이터 처리 작업(순차적이든 병렬적이든)을 돕고자 자바8에 추가되었다. 이 API가 제공하는 추상 개념 중 핵심은 두 가지다. 스트림(Stream)은 데이터 원소의 유한 혹은 무한 시퀀스(sequence)를 의미 스트림 파이프라인(Stream Pipeline)은 이 원소들로 수행하는 연산단계를 표현하는 개념 스트림 안의 데이터 원소들은 객체 참조(reference)나 기본 타입(int, long, double)을 지원 메서드 연쇄를 지원하는 플루언트 API다. 파이프라인 하나를 구성하는 모든 호출을 연결하여 단 하나의 표현식으로 완성할 수 있다. 파이프라인 여러 개를 연결해 표현식 하나로 만들 수 있다. 스트림 파이프라인 소스 트림에서 시작해 종단 연산으로 끝나며, ..
2023.05.17 -
[아이템 43] 람다보다는 메서드 참조를 사용하라
메서드 참조(Method Reference) 함수를 메서드의 파라미터로 전달하는 것을 메서드 참조 class::methodName 구문을 사용하여 클래스 또는 객체에서 메서드를 참조 람다식(Lambda Expression)의 가장 큰 장점 중 하나는 코드가 짧아진다는 것인데, 람다식에 메서드 참조를 사용하면 코드를 더 간결하고 가독성 있게 만들 수 있다. ※ 자바8 Map merge 메서드 키, 값, 함수를 인수를 받으며, 주어진 키가 맵 안에 없다면 주어진 [키, 값] 쌍을 그대로 저장 주어진 키가 맵 안에 있다면 함수(세번째 인수로 받은)를 현재 값과 주어진 값에 적용한 다음, 그결과로 현재 값을 덮어쓴다. 즉, [키, 함수의 결과] 쌍을 저장한다. Map keyCount = new HashMap()..
2023.05.13 -
[아이템 42] 익명 클래스보다는 람다를 사용하라
람다란? 자바 8에서 추상 메서드 하나만 가지고 있는 인터페이스를 함수형 인터페이스라고 부른다. 이 인터페이스들의 인스턴스를 람다식(lambda expression, 혹은 짧게 람다)를 사용해 만들 수 있다. 예) 문자열 길이순으로 정렬 정렬을 위한 비교 함수로 익명 클래스 사용 익명 클래스의 인스턴스를 함수 객체로 사용 - 낡은 기법 Comparator 인터페이스가 정렬을 담당하는 추상 전략을 뜻하며, 구체적인 전략을 익명 클래스로 구현 Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); 람다식을 함수 ..
2023.05.12