개발서적

    [Effective Java] 스트림에서는 부작용 없는 함수를 사용하라

    스트림 패러다임 스트림 패러다임의 핵심은 계산을 일련의 변환으로 재구성하는 부분이다. 이때 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수이여야 한다. 순수 함수 오직 입력만이 결과에 영향을 주는 함수 스트림의 잘못된 사용 예시 Map freq = new HashMap(); try (Stream words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); }) } 위 코드는 외부 상태(빈도표)를 수정하는 람다를 실행하면서 문제가 생긴다. (merge) forEach 연산은 스트림 계산 결과를 보여주는 일 이상을 하지 않는 것이 좋다. 잘 사용한 예시..

    [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부터 추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정받아 인스턴스를 람다식을 사용..