* 람다식
- 메서드(함수)를 하나의 식으로 표현한 것
- 문법 : (매개변수 목록 -> {실행문}
- 장점
1. 코드를 간결하게 만들 수 있다.
2. 코드가 간결하고 식에 개발자의 의도가 명확하게 드러나므로 가독성이 향상된다.
3. 함수(메서드)를 만드는 과정 없이 한 번에 처리할 수 있기에 코딩하는 시간이 줄어든다.
- 단점
1. 익명 함수는 재사용이 불가능하다.
2. 디버깅이 다소 까다롭다.
3. 람다식을 남발하면 코드가 지저분해진다.(비슷한 코드의 중복 가능성 높음)
4. 재귀로 만들 경우에는 다소 부족한 면이 있다. (재귀함수 : 자신을 재참조하는 함수)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package day25;
// 람다식 ==> 메서드(함수)를 하나의 식으로 표현한 것
//하나의 자바 파일에 하나의 클래스만 둘 수 있음
//밀접한 경우에는 클래스나 interface가 얹혀져 있을 수 있음
interface Oper{
public int addOne(int a);
}
// 인터페이스 구현 > 클래스! 따라서, 추상메서드 override 필요
class Test implements Oper{
@Override
public int addOne(int a) {
// return 0;
return a*2; // add3에서 a*2추가
}
}
public class LamdaEx1 {
public static void main(String[] args) {
// 인터페이스는 new 불가
// ==> 인스턴스화 할 수 없음
// Oper add = new Oper(); >> 불가능!
// Oper add = 인터페이스를 구현한 객체;
// Test t = new Test(); // 위에서 클래스화(인터페이스 구현)해서 인스턴스화 가능
// Oper add = t; // 따라서, 참조값 주는 것이 가능
// 하지만 한 번만 쓸거라면 굳이 클래스화할 필요 없음 > 이름 주지 않고 그냥 만듦
// Test 클래스 만들지 말고,
Oper add = new Oper() { // add unimplements method : 미구현 메서드 추가 >> 익명 이너 클래스
// 익명 이너 클래스 : 내부에서 정의하는, 이름이 없는 클래스..
@Override
public int addOne(int a) {
// TODO Auto-generated method stub
return a*2;
}
}; // add end
System.out.println(add.addOne(100)); // addOne의 인수를 주고 리턴
// 줄여서 쓰는 방법..<람다식> 두가지 다 사용 가능
Oper add2 = (a) -> a*2;
System.out.println(add2.addOne(100));
Oper add3 = new Test();
System.out.println(add3.addOne(100));
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package day25;
// 람다식 특징
// 문법
// (매개변수 목록) -> {실행문}
// 장점
// 1. 코드를 간결하게 만들 수 있다.
// 2. 코드가 간결하고 식에 개발자의 의도가 명확하게 드러나므로 가독성이 향상된다.
// 3. 함수(메서드)를 만드는 과정 없이 한 번에 처리할 수 있기에 코딩하는 시간이 줄어든다.
// 단점
// 1. 익명 함수는 재사용이 불가능하다.
// 2. 디버깅이 다소 까다롭다.
// 3. 람다식을 남발하면 코드가 지저분해진다.(비슷한 코드의 중복 가능성 높음)
// 4. 재귀로 만들 경우에는 다소 부족한 면이 있다. (재귀함수 : 자신을 재참조하는 함수)
interface Caculator {
int cal(int a, int b); // 두 수의 합을 구하는 메서드
}
public class LamdaEx2 {
public static void main(String[] args) {
Caculator c;
c = (a, b) -> {return a + b; }; // 람다식
System.out.println(c.cal(100, 200));
}
}
|
cs |
- 2개의 매개변수와 리턴 값이 없는 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package day25;
// 2개 매개변수와 리턴 값이 없는 경우
interface Calculate {
void cal (int a, int b);
}
public class LamdaEx3 {
public static void main(String[] args) {
Calculate c;
c = (a,b) -> {
System.out.println("---------------------");
System.out.println(a+b);
};
c.cal(4, 3);
c = (a, b) -> System.out.println(a-b);
// if()
// 문장1;
// 위의 if문의 문장이 하나라 중괄호 생략한 것처럼, 람다식도 문장이 한 줄이면 중괄호 생략 가능
c.cal(100, 50);
}
}
|
cs |
- 람다 표현식 : 다양한 람다식 표현방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package day25;
interface Printable{
void print(String msg);
}
public class LamdaEx4 {
public static void main(String[] args) {
Printable p;
p = (String s) -> {
System.out.println(s);
};
p.print("람다 표현식 1번 ");
System.out.println("--------------------");
// {}에 문장이 1개라면 {}를 생략 가능
// 리턴값이 없을 때만 가능
p = (String s) -> System.out.println(s);
p.print("람다 표현식 2번 ");
System.out.println("--------------------");
// 매개변수의 정보가 있어서 타입을 추론(유추) 할 수 있다면
// 자료형을 생략 가능
p = (s) -> System.out.println(s);
p.print("람다 표현식 3번 ");
System.out.println("--------------------");
// 매개변수가 1개만 존재한다면 ()도 생략할 수 있다.
p = s -> System.out.println(s);
p.print("람다 표현식 4번 ");
System.out.println("--------------------");
}
}
|
cs |
- 익명 이너 클래스와 람다식
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
package day25;
// 익명 이너 클래스용
interface Merge{ // 인터페이스
// 추상메서드
public int add(int a, int b);
public int minus(int a, int b);
}
// 처음부터 람다식을 쓸 수 있는 인터페이스라는 것을 처음부터 정의할 수 있을까?
// 인터페이스에 @FunctionalInterface 추가
// 람다식용
@FunctionalInterface
interface Merge2{ // 인터페이스
// 추상메서드
public int add(int a, int b);
// public int minus(int a, int b); => 람다식은 메서드가 2개면 안돼서 생략
}
public class LamdaEx5 {
public static void main(String[] args) {
// 1. 익명 이너 클래스
Merge m;
m = new Merge() { // 미구현 메서드 추가
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public int minus(int a, int b) {
return a-b;
}
};
System.out.println(m.add(100, 200));
System.out.println(m.minus(100, 200));
System.out.println("---------------------");
// 2. 람다식
// 람다식은 메서드 이름을 알기 때문에 안쓰는데,
// 메서드가 2개라면 어떤 메서드인지 알 수 없음
// 따라서, 인터페이스의 추상메서드가 단 하나여야만 람다식을 사용할 수 있다.
Merge2 m2;
m2 = (a, b) -> a+b;
System.out.println(m2.add(200, 300));
}
}
|
cs |
- Generic을 활용한 람다식
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package day25;
@FunctionalInterface // 람다식을 사용할 수 있는 인터페이스다.
interface MathUtil<T> { // 아직 타입(자료형) 미지정 : Generic
T cal(T a, T b);
}
public class LamdaEx6 {
public static void main(String[] args) {
MathUtil<Integer> mu; // int
mu = (a, b) -> a+b;
System.out.println(mu.cal(100, 200)); // 300
MathUtil<String> mus; // String
mus = (a, b) -> a+b; // String은 더하면 '+'가 연결 연산자로 쓰임
System.out.println(mus.cal("푸른하늘", "은하수")); // 푸른하늘은하수
MathUtil<Float> append; // Float
append = (a, b) -> a+b;
System.out.println(append.cal(300.0f, 200.0f)); // 500.0
}
}
|
cs |
- 1부터 100사이의 수를 랜덤하게 10개 뽑아 ArrayList에 담기
> 각각 기존 방법과 람다식으로..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package day25;
import java.util.ArrayList;
import java.util.Random;
public class LamdaEx7 {
public static void main(String[] args) {
// 1부터 100 사이의 수를 랜덤하게 10개를 뽑아서
// ArrayList에 담기
// list
// ArrayList <== integer를 담는 전용 : list
ArrayList<Integer> list = new ArrayList(); // Generic Integer
// Random 객체 생성
Random rnd = new Random();
for(int i=0; i<10; i++) {
list.add(rnd.nextInt(100)+1); // 1부터 100 사이의 정수값 구하기
} // 10번 반복
// nextInt() <--
// arraylist에 담기
System.out.println("list : "+list);
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package day25;
import java.util.ArrayList;
import java.util.Random;
// 람다식 사용
@FunctionalInterface
interface MakeList<T>{
public int make();
}
public class LamdaEx8 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
MakeList<Integer> mlist = () -> { // 매개변수 없음
Random rnd = new Random();
return rnd.nextInt(100)+1;
};
for(int i=0; i<10; i++) { // 리스트에 10개 집어넣기
list.add(mlist.make());
}
System.out.println("list : "+list);
}
}
|
cs |
- java.util.function.Supplier 활용 > get()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package day25;
import java.util.ArrayList;
import java.util.Random;
import java.util.function.Supplier;
// 미리 정의되어 있는 인터페이스 사용 : 람다식
// java.util.function 밑에 있는 미리 정의되어 있는 함수적 인터페이스
public class LamdaEx9 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
Supplier<Integer> mlist = () -> { // Supplier
Random rnd = new Random();
return rnd.nextInt(100)+1;
};
for(int i=0; i<10; i++) {
list.add(mlist.get()); // get
}
System.out.println("list : "+list);
}
}
|
cs |
- java.util.function.Consumer;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package day25;
import java.util.function.Consumer;
public class LamdaEx10 {
public static void main(String[] args) {
Consumer<String> c = s -> System.out.println(s);
c.accept("오늘은");
c.accept("수요일");
}
}
|
cs |
- Supplier과 Consumer, Function. Predicate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
package day25;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class LamdaEx11 {
public static void main(String[] args) {
// Supplier<T>
// 인자는 받지 않으며 리턴타입만 존재하는 메서드
// 순수함수에서 결과를 바꾸는 것은 INPUT 뿐이다.
Supplier<String> s = () -> "Hello Supplier";
String result = s.get(); // 문자열에 넣고
System.out.println(result); // 꺼내어 출력
// Consumer<T>
// 리턴을 하지 않고 (void) 매개변수를 받는 메서드를 갖고 있다.
// 매개변수를 받아 소모한다는 의미
Consumer<String> c = str -> System.out.println(str);
c.accept("Hello Lamda");
// Function<T, R>
// 전형적인 함수를 지원
// 하나의 매개변수와 리턴 타입을 갖는다.
Function<String, Integer> f =
str -> Integer.parseInt(str); // String을 주면 int로 바꿔서 리턴
Integer result2 = f.apply("1"); // 문자 1을 숫자 1로
System.out.println(result2 + 100); // 1+100 = 101
// Predicate<T>
// 하나의 매개변수와 리턴타입을 갖는다.
// 리턴타입을 지정하는 타입 파라미터가 안보인다.
// 반환값은 Boolean
// Function<T, Boolean> 형태와 동일
Predicate<String> p = str -> str.isEmpty(); // 결과는 항상 boolean이라 따로 지정 x
// isEmpty : 문자열이 텅텅 비었니? > 비었으면 true, 문자가 있으면 false 리턴
boolean result3 = p.test("hello");
System.out.println(result3);
// 위의 항목들을 필요할 때 가져다 쓰기 ~.~
}
}
|
cs |
'Java' 카테고리의 다른 글
[Java] Paint Method (0) | 2023.04.06 |
---|---|
[Java] 부서 검색 창 + 부서 등록 (DAO, getOne, addOne) (0) | 2023.04.05 |
[Java] DAO(Data Access Object) / VO(Value Object) - MemberDAO (0) | 2023.04.05 |
[Java] DAO(Data Access Object) / VO(Value Object) (0) | 2023.04.04 |
[Java] JDBC - 데이터 베이스 활용 (로그인, 회원가입 창 + 중복확인) (0) | 2023.03.31 |