728x90

- 자바는 8 버전부터 객체지향 언어임에도 불구하고 함수형 프로그래밍 기법 사용이 가능해졌다.
- 함수형 프로그래밍은 함수를 중심으로 프로그래밍하는 기법인데, 코드 가독성과 유지보수 확보를 위해 사용한다.
- 자바에서 메소드는 무조건 클래스 안에 존재해야 하는데(객체 지향 언어이기 때문), 함수형 프로그래밍에서는 가능해졌다. 메소드를 객체 생성 없이 사용할 수 있다는 것을 의미한다.

- 함수형 프로그래밍에서는 람다식과 함수형 인터페이스를 사용하여 함수를 표현하게 된다.
- 함수형 인터페이스는 단 하나의 추상 메소드를 가지는 인터페이스이다.
- 함수형 인터페이스는 @FunctionalInterface 라는 Annotation 이 사용된 것을 볼 수 있다. Annotation 은 특정 제약사항을 걸어줄 때 사용하는데, 함수형 인터페이스 Annotation 은 단 하나의 추상 메소드를 가지게 만든다.

- 람다식은 함수 이름, 반환타입, 매개변수 타입을 생략한다.
- 바디 코드가 짧은 경우(한 줄일 경우) { } 중괄호 & return 키워드를 생략할 수 있다.
package lambda;
@FunctionalInterface
interface MyNumber {
int add(int num1, int num2);
}
public class Ex1 {
public static void main(String[] args) {
MyNumber number = (x, y) -> x+y;
System.out.println(number.add(10, 20));
}
}
- 람다식은 식처럼 보이는데 사실은 메서드 선언에 가깝다는 것을 생각해야 한다.
package lambda;
@FunctionalInterface
interface MyNumber2 {
int add(int num1, int num2);
}
public class Ex2 {
public static void main(String[] args) {
//MyNumber number = (x, y) -> x + y;
MyNumber2 number2 = new MyNumber2() {
@Override
public int add(int x, int y) {
return x+y;
}
};
// 람다식을 사용하지 않으니까 코드가 훨씬 길어진 것을 볼 수 있다.
System.out.println(number2.add(10, 20));
}
}
- 실제로 람다식이 처리되는 과정을 코드로 풀어쓴 것을 볼 수 있다. 람다식은 실제로 익명 클래스 형식으로 처리가 된다.
package lambda;
@FunctionalInterface
interface StringConcat {
public void makeString(String s1, String s2);
}
public class Ex3 {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "World";
//람다식 함수 사용
StringConcat concat1 = (str1, str2) -> System.out.println(str1 + "," + str2);
// 익명 클래스 사용
StringConcat concat2 = new StringConcat() {
@Override
public void makeString(String str1, String str2) {
System.out.println(str1 + "," + str2);
}
};
concat1.makeString(s1, s2);
concat2.makeString(s1, s2);
}
}
- 람다식 함수와 익명 클래스 사용은 같은 것이다.
package lambda;
import java.util.*;
public class Ex4 {
public static void main(String[] args) {
List<String> list = Arrays.asList("aaa", "ccc", "bbb");
// 익명클래스 넣기
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}
});
System.out.println("리스트 역정렬 : " + list);
// 람다식 함수 넣기
Collections.sort(list, (s1, s2) -> s1.compareTo(s2));
System.out.println("리스트 순정렬 : " + list);
}
}
- 다양한 코드에서 람다식 함수 사용이 더 간단한 것을 확인할 수 있다.
연습문제
람다식과 함수형 인터페이스를 사용하여 두 숫자 중 더 큰 값을 반환하는 함수를 만드세요.
ex. max(10, 20) -> 20
package lambda;
@FunctionalInterface
interface largerNumber {
public int max(int i1, int i2);
}
public class Q1 {
public static void main(String[] args) {
// 분기문 활용 & 람다식 활용
largerNumber l1 = (i1, i2) -> {
if (i1 < i2) {
return i2;
} else if (i1 == i2) {
return -999;
} else {
return i1;
}
};
// 삼항 연산자 활용 & 익명 클래스로 인터페이스 구현
largerNumber l2 = new largerNumber() {
@Override
public int max(int i1, int i2) {
return i1>i2? i1:i2;
}
};
// 삼항 연산자 활용 & 람다식 활용
largerNumber l3 = (x, y) -> x>y? x:y;
System.out.println(l1.max(10, 20));
System.out.println(l2.max(10, 20));
System.out.println(l3.max(10, 20));
}
}

연습문제2
배열의 합을 구하는 함수를 함수인터페이스와 람다식을 활용해서 만들어보세요.
package lambda;
@FunctionalInterface
interface Calculator {
int add(int arr[]);
}
public class Q2 {
public static void main(String[] args) {
int arr[] = {1, 2, 3, 4};
Calculator calculator = (intArr) -> {
int sum = 0;
for(int i=0; i<arr.length; i++) {
sum = sum + arr[i];
}
return sum;
};
System.out.println(calculator.add(arr));
}
}
'[그린컴퓨터] Server > JAVA(자바 JDK)' 카테고리의 다른 글
| 예외처리 { 예외클래스, 예외처리, 컴파일러의 예외체크, 예외처리미루기 } (0) | 2023.07.04 |
|---|---|
| 스트림 { 개요, 중간연산과 최종연산, 연산 종류, 연습문제 } (0) | 2023.07.04 |
| 내부클래스 { 개요, 종류, 제약사항, 익명 클래스 } (0) | 2023.07.03 |
| 컬렉션 프레임워크 { 정의, Collection 인터페이스, Map 인터페이스, 실습준비 } (0) | 2023.06.09 |
| 제네릭 { 제네릭, 제네릭의 선언 및 생성, 제네릭의 필요성, 제네릭 클래스 정의하기, T 자료형에 사용할 자료형을 제한하는 <T extends 클래스>, 제네릭 메서드 활용하기, 컬렉션 프레임워크, 제.. (0) | 2023.06.08 |