개발서적/Effective Java

    [Effective Java] 스트림은 주의해서 사용하라

    스트림의 등장 스트림 API는 다량의 데이터 처리 작업(순차 or 병렬)을 돕고자 자바 8에 추가되었다. 이 API가 제공하는 추상 개념 중 핵심은 두 가지다. 스트림 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻한다. 스트림 파이프라인 스트림 파이프라인은 이 원소들로 수행하는 연산 단계를 표현하는 개념이다. 소스 스트림에서 시작해 종단 연산으로 끝나며 중간에 하나 이상의 중간 연산이 들어갈 수 있다. 스트림 파이프라인은 지연평가 된다. 평가는 종단 연산이 호출될 때 이뤄지며, 종단 연산에 쓰이지 않는 데이터 원소는 계산이 쓰이지 않는다. 스트림의 단점 람다에서는 final이거나 사실상 final인 변수만 읽을 수 있고, 지역변수를 수정하는 건 불가능하다. 코드 블럭에서는 return, break,..

    [Effective Java] 표준 함수형 인터페이스를 사용하라

    java.util.function 패키지에는 다양한 용도의 표준 함수형 인터페이스가 담겨 있다. 기억해야 할 함수형 인터페이스 6개 Operator 인터페이스 - 반환값과 인수의 타입이 같은 함수 인수가 1개인 UnaryOperator 인수가 2개인 BinaryOperator T apply(T t) String::toLoswerCase T apply(T t1, T t2) BigInteger::add Predicate 인터페이스 - 인수 하나를 받아 boolean을 반환하는 함수 boolean test(T t) Collection::isEmpty Function 인터페이스 - 인수와 반환 타입이 다른 함수 R apply(T t) Arrays::asList Supplier 인터페이스 - 인수를 받지 않고 값..

    [Effective Java] 람다보다는 메서드 참조를 사용하라

    람다의 가장 큰 특징은 간결함이다. 하지만 이런 함수 객체를 람다보다 더 간결하게 만드는 방법이 있다. 메서드 참조 자바 Map에 있는 merge 메서드를 람다식으로 사용하면 다음과 같다. map.merge(key, 1, (count, incr) -> count + incr); 매개변수인 count와 incr는 크게 하는 일 없이 공간을 꽤 차지한다. 이 람다는 두 인수의 합을 단순히 반환할 뿐이다. 자바 8이 되면서 Integer 클래스는 이 람다와 기능이 같은 정적 메서드 sum을 제공하기 시작했다. map.merge(key, 1, Integer::sum); 하지만 때로는 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도 한다. 이런 람다는 길이는 더 길지만 메서드 참조보다 읽기 쉽고 유지보..

    [Effective Java] 익명 클래스보다는 람다를 사용하라

    익명 클래스의 등장 예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스를 사용했다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여, 특정 함수나 동작을 나타내는 데 썼다. 이런 익명 클래스는 이후에 함수 객체를 만드는 주요 수단이 되었다. Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } } 이런 익명 클래스 방식은 코드가 너무 길기 때문에 자바는 함수형 프로그래밍에 적합하지 않다. 람다식 자바 8부터 추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정받아 인스턴스를 람다식을 사용..

    [Effective Java] 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라

    마커 인터페이스 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스라 한다. Serializable 인터페이스가 가장 좋은 예로 Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸수 있다, 즉 직렬화 할 수 있다고 알려준다. 마커 애너테이션의 등장으로 마커 인터페이스는 사용이 안된다고 하지만 다음과 같은 이유로 마커 인터페이스가 마커 애너테이션보다 낫다. 마커 인터페이스의 장점 1. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있다. -> 마커 인터페이스는 타입이기 때문에, 마커 애너테이션을 사용했다면 런타임에야 발견될 오류를 컴파일 타임에 잡을 수 있..