|
6 | 6 | - 1. 컴파일 시 강한 타입체크를 하여 에러 방지
|
7 | 7 | - 2. 형변환을 제거한다. 지네릭이 아닌 코드는 불필요한 타입 변환을 하기 때문에 성능에 악영향을 미친다.
|
8 | 8 |
|
9 |
| - ``` |
| 9 | + ```java |
10 | 10 | // 비제네릭 코드
|
11 | 11 | List list = new ArrayList();
|
12 | 12 | list.add("hello");
|
13 | 13 | String str = (String)list.get(0);
|
14 | 14 | ```
|
15 | 15 |
|
16 |
| - ``` |
| 16 | + ```java |
17 | 17 | //제네릭 코드
|
18 | 18 | List<String> list = new ArrayList<String>();
|
19 | 19 | list.add("hello");
|
|
42 | 42 | - 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드
|
43 | 43 | - 리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터를 기술한 다음, 리턴 타입과 매개타입으로 타입 파라미터를 사용하면 된다.
|
44 | 44 |
|
45 |
| - ``` |
| 45 | + ```java |
46 | 46 | public <T> Box<T> boxing (T t) { ... }
|
47 | 47 | ```
|
48 | 48 |
|
49 |
| - ``` |
| 49 | + ```java |
50 | 50 | public <타입파라미터..> 리턴타입 메소드명 (매개변수..) { ... }
|
51 | 51 | ```
|
52 | 52 |
|
53 | 53 | - 제네릭 메소드는 두가지 방식으로 호출할 수 있다.
|
54 | 54 |
|
55 | 55 | 1. 타입 파라미터를 명시적으로 Integer로 지정
|
56 |
| - ``` |
| 56 | + ```java |
57 | 57 | Box<integer> box = <Integer>boxing(100);
|
58 | 58 | ```
|
59 | 59 |
|
60 | 60 | 2. 매개값을 보고 구체적 타입을 추정. 타입 파라미터를 Integer로 추정
|
61 |
| - ``` |
| 61 | + ```java |
62 | 62 | Box<integer> box = boxing(100);
|
63 | 63 | ```
|
64 | 64 |
|
|
88 | 88 | ## 13.7 제네릭 타입의 상속과 구현
|
89 | 89 | - 제네릭 타입도 부모 클래스가 될 수 있다.
|
90 | 90 |
|
91 |
| - ``` |
| 91 | + ```java |
92 | 92 | public class ChildProduct<T,M> extends Product<T,M> { ... }
|
93 | 93 | ```
|
94 | 94 | - 자식 제네릭 타입은 추가적으로 타입 파라미터를 가질 수 있다.
|
|
97 | 97 |
|
98 | 98 |
|
99 | 99 |
|
| 100 | +# 14.람다식 |
100 | 101 |
|
| 102 | +## 14.1 람다식이란? |
| 103 | +자바는 객체 지향 프로그래밍이 유행이던 시기에 디자인된 언어, 최근들어 함수적 프로그래밍이 부각되고 있다. |
| 104 | +객체 지향 프로그래밍 + 함수형 프로그래밍을 혼합하여 더욱 효율적인 프로그래밍이 될 수 있도록 언어는 발전되는중. |
101 | 105 |
|
| 106 | +**자바는 함수적 프로그램을 위해 람다식을 지원한다.** |
102 | 107 |
|
| 108 | +1. 코드가 간결해진다 |
| 109 | +2. 컬렉션 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있다. |
| 110 | +3. 람다식의 형태는 매개 변수를 가진 코드 블록이지만, 런타임 시에는 익명 구현 객체를 생성한다. |
103 | 111 |
|
| 112 | +> 람다식은 "(매개변수) -> {실행코드}" 형태로 작성된다. |
104 | 113 |
|
| 114 | +-> 함수 정의 형태를 띄고 있지만 런타임 시에 인터페이스의 익명 구현 객체로 생성된다. |
105 | 115 |
|
106 |
| -# 14.람다식 |
107 |
| -
|
108 |
| -## 14.1 람다식이란? |
109 | 116 | ## 14.2 람다식 기본 문법
|
| 117 | +> (타입 매개변수, ...) -> { 실행문; ... } |
| 118 | + |
| 119 | +- '->' 기호는 매개 변수를 이용해서 중괄호 '{}'를 실행한다는 뜻으로 해석하면 된다. |
| 120 | +- 하나의 매개변수만 있다면 괄호()를 생략할 수 있고, 하나의 실행문만 있다면 중괄호 {}도 생략할 수 있다. |
| 121 | + > a -> {system.out.println(a); } |
| 122 | +- 만약 매개변수가 없다면 빈 괄호를 반드시 사용 |
| 123 | + > () -> {system.out.println(a); } |
| 124 | +- 중괄호 {}에 return 문만 있을 경우 return 문을 사용하지 않고 다음과 같이 작성하는 것이 정석 |
| 125 | + > (x,y) -> x + y |
| 126 | + |
110 | 127 | ## 14.3 타겟 타입과 함수적 인터페이스
|
| 128 | +- 자바는 메소드를 단독으로 선언할 수 없고 항상 클래스의 구성 멤버로 선언하기 때문에 람다는 이 메소드를 가지고 있는 객체를 생성해낸다. |
| 129 | +- 인터페이스는 직접 객체화 할수 없기 때문에 구현 클래스가 필요 |
| 130 | +- 람다식은 익명 구현 클래스를 생성하고 객체화한다. |
| 131 | +- 대입될 인터페이스의 종류에 따라 작성 방법이 달라지기 때문에 람다식이 대입될 인터페이스를 람다식의 타겟 타입(target type) 이라 한다. |
| 132 | + |
| 133 | +### 함수적 인터페이스 (@FunctionalInterface) |
| 134 | +- 모든 인터페이스를 람다식의 타겟 타입으로 사용할 수 없다. 람다식이 하나의 메소드를 정의하기 때문에 두개이상의 추상 메소드가 선언된 인터페이스는 람다식을 이용해서 구현 객체를 생성할 수 없다. |
| 135 | +- 하나의 추상 메소드가 선언된 인터페이스만이 람다식의 타겟 타입이 될 수 있는데, 이러한 인터페이스를 함수적 인터페이스라고 한다. |
| 136 | +- 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체킹해주는 기능 |
| 137 | + > @FunctionalInterface : 두개이상의 추상 메소드가 선언되면 컴파일 오류 발생시킴 |
| 138 | + |
| 139 | +### 매개변수와 리턴값이 없는 람다식 |
| 140 | + ```java |
| 141 | + @FunctionalInterface |
| 142 | + public interface MyFunctionalInterfacfe { |
| 143 | + public void method(); |
| 144 | + } |
| 145 | + ``` |
| 146 | +- 매개변수도 없고 리턴값도 없다 |
| 147 | +- 이 인터페이스를 타겟타입으로 갖는 람다식은 다음과 같이 작성한다. |
| 148 | +- 람다식에서 매개변수가 없는 이유는 method()가 매개변수를 갖지 않기 때문이다. |
| 149 | + |
| 150 | + |
| 151 | + ```java |
| 152 | + MyFunctionalInterface fi = () -> { } |
| 153 | + ``` |
| 154 | + |
| 155 | +### 매개 변수가 있는 람다식 |
| 156 | + |
| 157 | + ```java |
| 158 | + @FunctionalInterface |
| 159 | + public interface MyFunctionalInterfacfe { |
| 160 | + public void method(int x); |
| 161 | + } |
| 162 | + ``` |
| 163 | +- 매개변수가 있고 리턴값이 없다. |
| 164 | + |
| 165 | + ```java |
| 166 | + MyFunctionalInterface fi = (x) -> { } 또는 x -> { } |
| 167 | + ``` |
| 168 | +- fi.method(5)로 호출 가능 |
| 169 | + |
| 170 | +### 리턴값이 있는 람다식 |
| 171 | + ```java |
| 172 | + @FunctionalInterface |
| 173 | + public interface MyFunctionalInterfacfe { |
| 174 | + public int method(int x, int y); |
| 175 | + } |
| 176 | + ``` |
| 177 | +- 매개변수가 있고 리턴값도 있다. |
| 178 | + |
| 179 | + ```java |
| 180 | + MyFunctionalInterface fi = (x,y) -> {...; return 값; } |
| 181 | + ``` |
| 182 | + |
111 | 183 | ## 14.4 클래스 멤버와 로컬 변수 사용
|
| 184 | +- 클래스의 멤버는 제약 사항 없이 사용 가능하지만, 로컬 변수는 제약 사항이 따른다. |
| 185 | + |
| 186 | +### 클래스의 멤버 사용 |
| 187 | +- this 키워드 사용할 때 주의할 것 |
| 188 | +- 람다식에서 this는 내부적으로 생성되는 익명 객체의 참조가 아니라, 람다식을 실행한 객체의 참조이다. |
| 189 | + |
| 190 | +### 로컬 변수 사용 |
| 191 | +- 람다식은 메소드 내부에서 주로 작성되기 때문에 로컬 익명 구현 객체를 생성시킨다. |
| 192 | +- 바깥 클래스의 필드나 메소드는 제한 없이 사용할 수 있으나, 메소드의 매개 변수또는 로컬 변수를 사용하면 이 두 변수는 final 특징을 가져야 한다. (9강.5.3 익명객체의 로컬 변수 사용 참고) |
| 193 | +- 매개 변수 또는 로컬 변수를 람다식에서 읽는 것은 허용하지만, 람다식 내부 or 외부에서 변경은 어렵다. |
| 194 | + |
| 195 | + |
112 | 196 | ## 14.5 표준API의 함수적 인터페이스
|
| 197 | +- 한개의 추상 메소드를 가지는 인터페이스들은 모두 람다식을 이용해서 익명 구현 객체로 표현 가능 |
| 198 | +  |
| 199 | + |
113 | 200 | ## 14.6 메소드 참조
|
| 201 | +- 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어, 람다식에서 불필요한 매개 변수를 제거하는 것이 목적. |
0 commit comments