두괄식으로 이 글의 요약을 처음에 작성하겠다. 까불지 말고 자바에서 기본으로 제공하는 Funtional Interface를 사용해라 사용자 정의 Funtional Interface를 정의해야 할 때도 있다. 그 규칙을 만족하는 경우에만 사용하는 것이 바람직하다.(그런 경우는 아래에서 다루겠다.) 과거에는 객체의 커스텀 함수를 정의하기 위해선 원본 객체를 상속받는 객체를 정의하고, 수정하고 싶은 메소드를 Overriding(재정의)해서 사용했다. 이를 템플릿 메소드 패턴이라고 한다. 그러나 람다가 도입되면서 클라이언트에서 커스텀 함수를 정의하는 방식에 Funtional Interface를 도입하는 것이 현대적인 방법이 됐다. 예시를 들어보자. LinkedHashMap의 removeEldestEntry 메소..
사람들은 참 게으르다. 람다식으로 소스 코드를 상당히 간소화시켰지만 이를 더 줄이려 한다. 그 방법이 메소드 참조이다. // map.merge를 이용해 구현한 빈도표 - 람다 방식과 메서드 참조 방식을 비교해보자. (259쪽) public class Freq { public static void main(String[] args) { Map frequencyTable = new TreeMap(); for (String s : args) frequencyTable.merge(s, 1, (count, incr) -> count + incr); // 람다 System.out.println(frequencyTable); } } remappingFuction은 BiFunction의 구현체이다. BiFunction..
아래의 글에서, 책에서 다루는 내용 외에 람다가 어떻게 구현되는지를 깊게 다룹니다. 채널 고정~ ^^7 익명 클래스 아이템 24 위의 글을 보고 오면 익명 클래스(anonymous classes)를 이해하기 쉽다. 익명 클래스를 통해 콜렉션을 정렬하는 예시이다. public static void main(String[] args) { List words = Arrays.asList(args); // 코드 42-1 익명 클래스의 인스턴스를 함수 객체로 사용 - 낡은 기법이다! (254쪽) Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s..
마커 인터페이스 아무런 메소드를 담지 않고 해당 클래스가 특정 속성임을 표시하기 위해 정의된 인터페이스 Serializable이 좋은 예시이다. Serializable을 implements한 클래스는 ObejctOutputStream을 통해 직렬화할 수 있다고 가르쳐 준다. 마킹을 하는 용도로 지난 아이템들에서 어노테이션을 살펴봤었다. 마킹의 용도에 있어 어노테이션에 비해 인터페이스의 장점은 클래스의 인스턴스를 구분할 수 있다. public final void writeObject(Object obj) throws IOException { // Serializable을 파라미터로 받으면 좋았을 듯 if (enableOverride) { writeObjectOverride(obj); return; } tr..
오버라이딩과 오버로딩의 차이를 말씀해 주세요~ 신입 개발자 면접 질문 목록에 단골로 등장하는 질문이다. (근데 이거 진짜 물어보나?..) 위 질문에 답할 수 있다면 매우 쉬운 내용이다. 아래의 소스 코드에서 버그를 찾아보자 import java.util.*; // 코드 40-1 영어 알파벳 2개로 구성된 문자열(바이그램)을 표현하는 클래스 - 버그를 찾아보자. (246쪽) public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = second; } public boolean equals(Bigram..
어노테이션의 두 가지 성질 스포 어노테이션은 그저 마킹하는 용도이다. 어노테이션 혼자서는 어떠한 동작도 하지 않는다. 어노테이션을 동작하게 하려면 또 다른 코드가 필요하다. 위의 배경지식을 알고 가면 이해하기 쉬울 것 같다. 명명 패턴이란? 주어진 규칙에 맞게 메소드, 클래스 이름 등을 정의하는 것이다. 규칙에 맞게 작성했다면 라이브러리나 프레임워크가 이를 읽어 어떤 로직을 처리해 준다. 예시로 JPA가 있다. 그러나 이런 패턴 작성을 개발자에게 맡기면.. 오타를 낼 수 있다. 올바른 요소에서 사용되는지 보장할 수 없다. 테스트 프레임워크인 JUnit이 예시로 등장한다. 과거 JUnit은 테스트를 수행하기 위해 method의 이름을 test로 시작하는 패턴에 대해서만 테스트가 수행되게 했다. 이런 오타를..
enum type의 성질들이다. 컴파일 시 final로 선언된다. 컴파일 시 Enum class를 상속받는다. 개발자가 생성자를 정의할 수 없다. 위의 특징들을 보면서 무엇이 느껴지는가? 이미 상속을 받아 상속을 받을 수 없고 (다중 상속) final로 선언되어 enum을 상속할 수도 없다. (extends는 직역하면 확장이지만 익숙한 상속으로 쓰겠음 -> 이하 확장) 그러나 enum type에서 확장의 효과를 누릴 수 있는 법이 있다. interface를 구현하는 법이다. // 코드 38-1 인터페이스를 이용해 확장 가능 열거 타입을 흉내 냈다. (232쪽) public interface Operation { double apply(double x, double y); } // 코드 38-1 인터페이스..
// 식물을 아주 단순하게 표현한 클래스 (226쪽) class Plant { enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Override public String toString() { return name; } } 식물을 표현하는 클래스이다. 식물들 마다 한해살이, 여러해살이, 두해살이와 같은 생애 주기가 존재한다. public static void main(String[] args) { Plant[] garden = {..
ordinal method는 enum type의 상수가 몇번째 존재하는지를 반환하는 함수이다. public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public int numberOfMusicians(){return ordinal() + 1;} } 합주단의 종류를 나열한 enum이다. 각각 1명부터 10명까지 합주단의 수에 따라 종류가 달라진다. 각각 index가 0 ~ 9까지 매칭되어 있기 때문에 ordinal() 메소드로 1 ~ 10까지의 값을 반환할 수 있다. 배열에서 어떤 값을 얻어내기 위해 그 배열의 인덱스 값을 참조한다는 뜻이다. 이럴 경우에 중복 된 값을 가질 수 없고, {..