<이펙티브 자바> 7. 람다와 스트림
by BFine반응형
www.yes24.com/Product/Goods/65551284
42. 익명클래스 보다는 람다를 사용하자
-
익명클래스 방식
- 코드가 너무 길어서 함수형 프로그래밍에는 부적합!
-
람다 방식
- 컴파일러가 대신 문맥을 살펴 타입을 추론 → 웬만하면 모든 매개변수 타입은 생략하는 것이 좋다
-
자바 8 List의 sort
words.sort(comparingInt(String::length)) default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } }
-
람다는 이름없고 문서화도 못하기 대문에 코드 자체로 동작이 설명되지 않거나 코드 줄수가 많아질때는 쓰지말자
- 길어야 3줄일때 사용하자
-
추상 클래스의 인스턴스를 만들때는 익명클래스를 사용해야 한다
-
람다는 자신을 참조 할 수 없다 → this는 바깥 인스턴스를 가르킴
43. 람다보다는 메서드 참조를 사용하자
- :: 연산자를 사용하면 해당 클래스의 static 메서드를 참조 할 수 있다.
- 참조 유형 4가지 차이가 뭔지 잘모르겠음
44. 표준 함수형 인터페이스를 사용하자
- 예로 LinkedHashMap의 removeEldestEntry 가장 오래된 녀석을 제거
- 필요한 용도에 맞는게 있다면 구현하지말고 표준 함수형 인터페이스 메서드를 활용하자
- 직접만든 함수형 인터페이스는
@FunctionalInterface
를 사용하자
45. 스트림은 주의해서 사용하자
- 스트림은 데이터 원소의 유무한 시퀀스를 뜻한다
- 스트림 파이프라인은 이 원소들로 수행하는 연산 단계를 표현하는 것
- 파이프라인은 소스 스트림에서 시작해 종단 연산으로 끝남
- 각 중간 연산은 스트림을 어떠한 방식으로 변환한다
- 스트림 API는 파이프라인 하나를 구성하는 모든 호출을 연결하여 하나의 표현식으로 완성
- 스트림 처리 어려운것
- 파이프라인을 통과할때 각단계에서 값 들에 동시 접근이 어렵다
46. 스트림에서는 부작용 없는 함수를 사용하자
-
아래 코드는 스트림 코드를 가장한 반복적 코드이다
Map<String,Long> freq = new HashMap<>(); words.forEach(word -> {freq.merge(word.toLowerCase(),1L,Long::sum)})
- 모든작업이 종단 연산에서 일어나고 외부상태(freq)를 수정하는 람다를 실행 (결국 람다에서는 상태수정만 발생)
- forEach 연산은 스트림 계산 결과를 보고할때 이외에 사용하지말자
-
Collectors
- 생성하는 객체는 일반적으로 컬렉션(toList, toSet, toCollection)
- toMap
- groupBy
- joining
47. 리턴 타입으로는 스트림보다는 컬렉션이 낫다
- 스트림은 반복을 지원하지 않는다
- 반복과 스트림을 알맞게 조합해야 좋은 코드가 나온다
- Stream이 Iterable을 확장하지 않아서 for-each로 스트림을 반복할 수 없다
48. 스트림 병렬화는 주의해서 적용해라
-
병렬 프로그래밍
- 안전성과 응답 가능 상태를 유지해햐함
-
메르센 소수 찍기
public static void main(String[] args){ primes().map(p->TWO.pow(p.intValueExact()).subtract(ONE)) // int형태로 추출 .filter(mer->mer.isProbablePrime(50)) .limit(20) .forEach(System.out::println) } Stream<BigInteger> primes(){ return Stream.iterate(TWO,BigInteger::nextProbablePrime); }
- 위를 parallel로 호출할 경우 아무것도 출력 못하면서 CPU는 90프로를 잡아먹는 상태가 계속된다
- 스트림 라이브러리가 병렬화 하는 방법을 찾지 못함
- Stream.iterate거나 중간 연산에 limit를 쓰면 병렬로 성능 개선을 기대 할 수 없다
- 위를 parallel로 호출할 경우 아무것도 출력 못하면서 CPU는 90프로를 잡아먹는 상태가 계속된다
-
ArrayList, HashMap, HashSet, ConcurrentHashMap, 배열, int&long 범위 일때 병렬 효과가 가장 좋다
- 참조 지역성이 뛰어난 특징 -> 메모리에 연속해서 저장되어 있음
- 참조 지역성이 낮을 경우 스레드는 데이터가 주메모리에서 캐시 메모리로 전송 되어 오기를 기다리며 긴 시간을 보낸다
-
종단 연산 중 가장 병렬 수행에 좋은 것은 reduce 이다. (가변 reduce는 좋지 않다)
-
병렬을 사용하여 출력할때 순서대로 출력하고 싶다면 forEachOredered 를 사용하자
-
스트림을 잘못 병렬화 하면 오동작 + 성능 저하가 발생
반응형
'개발서적 > 이펙티브 자바' 카테고리의 다른 글
<이펙티브 자바> 10. 예외 (0) | 2021.01.24 |
---|---|
<이펙티브 자바> 8. 메서드 (0) | 2021.01.21 |
<이펙티브 자바> 6. 열거 타입과 애너테이션 (0) | 2021.01.15 |
<이펙티브 자바> 5. 제네릭 (0) | 2021.01.14 |
<이펙티브 자바> 4. 클래스와 인터페이스 (0) | 2021.01.12 |
블로그의 정보
57개월 BackEnd
BFine