아이템 46. 스트림에는 부작용 없는 함수를 사용하라. 스트림은 함수형 프로그래밍의 패러다임을 의미한다. 이 패러다임을 받아들여야 Stream의 이점을 가져갈 수 있음. 스트림은 일련의 계산을 변환(Transforming)하며 순차적으로 처리한다. 일련의 계산들은 순수함수들에 의해서 처리되어야 함. forEach()를 이용해 외부 객체의 상태를 업데이트 하는 작업을 하지 마라. (순수함수가 아니게 됨) 대신, Stream Collectors가 제공하는 함수 객체들을 이용해 업데이트 대신 새로운 Collection을 만들어라. Stream을 사용할 때는, Collectors가 제공하는 함수 객체를 잘 사용하자. toMap() toSet() toCollection() groupingBy() groupingB..
메서드 이름을 신중히 짓자 메서드 이름을 지을 때는 항상 표준 명명 규칙을 따라야 함. of(), newInstance() 같은 것들. 이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되게 짓는게 중요함. 클래스 / 인터페이스에 편의 메서드를 너무 많이 만들지 말자 메서드가 너무 많은 클래스는 사용/공부/문서화/테스트/유지보수하기 어려움. 인터페이스에 너무 많은 메서드가 존재하면, 구현하기 어려움. 매개변수 목록은 짧게 유지하자 매개변수는 4개 이하로 만들자. 그 이상이 되면, 메서드 호출에 어떤 매개변수가 필요했는지 기억하기 어려움. 만약 같은 타입의 매개변수가 연속되었을 때, 위치가 살짝 바뀌어도 컴파일되어 오류가 발생할 수 있음. 매개변수 목록을 짧게 줄여주는 방법 여러 메서드로 쪼개기 쪼개..
아이템 76. 가능한 한 실패 원자적으로 만들어라. 실패 원자성이란 실패 전후로 객체의 상태가 바뀌지 않는 것을 의미함. 실패한 후, 프로그램이 계속 진행된다면 이 때는 실패 원자적으로 만드는 것이 좋음. 실패 원자성 구현 방법 불변 객체로 만듦. 가변 객체의 경우 매개변수의 유효성 검사. 실패할 가능성이 있는 모든 코드를 객체의 상태를 바꾸는 코드보다 앞에 배치. 임시 복사본에서 작업 수행 후, 작업 성공되면 원래 객체와 교환하기 실패 원자성을 보장하지 않아도 되는 경우 실패 원자성을 달성하기 위한 연산의 비용 / 복잡도가 클 경우. ConcurrentModificationException이 발생한 경우. → 이미 콜렉션은 변했기 때문에 어떻게 할 수가 없음 실패 원자성이란? 특정 객체의 메서드를 실행..
Effective Java : 아이템 50. 적시에 방어적 복사를 만들라. 클라이언트의 악의적인 공격 / 실수에 의해 자바 객체의 불변식이 깨질 수 있음. 방어적 복사를 통해 불변식이 깨지는 것을 막아야함. 주의를 기울이지 않으면 다음 경우에 불변식이 깨짐 가변 객체를 매개변수로 받고, 그걸 방어적 복사 없이 인스턴스 필드로 사용하는 경우 (외부에서 해당 참조를가지고 있다면 수정 가능) 인스턴스의 메서드가 방어적 복사 없이 가변 객체를 반환하는 경우 (외부에서 수정 가능) 가변 객체의 예시는? 크기가 1이상인 배열 Collection Setter()가 열려있는 녀석들. 언제 방어적 복사를 안해도 될까? 클라이언트가 생성자에게 전달한 매개변수의 통제권을 클라이언트가 포기할 때 내부 필드가 모두 불변 객체일..
아이템 83. 지연 초기화는 신중히 사용하라 지연초기화는 성능 최적화 기법중 하나다. 따라서 안하는게 일단은 최선임. 지연 초기화란? Object lazy; // 수많은 코드 이후. lazy = new Object(); 지연 초기화는 필드가 필요한 시점까지 초기화하는 기법이다. 위의 코드가 간단한 예시이다. 지연 초기화는 '성능 최적화'를 위해 사용되는 기법 중 하나다. 따라서 안하는게 더 좋을 가능성이 있으며, 가급적이면 하지 않는 것이 좋다. 지연 초기화가 도움이 되는 경우 지연 초기화는 실제 필드가 필요한 시점까지 인스턴스를 생성하지 않는다. 이것이 도움이 되는 경우는 다음 조건을 모두 만족할 때다. 물론 만족한다고 해서 성능 개선을 항상 보장하지는 않는다. 초기화 비용이 크다. 이 필드가 잘 호출..