java : oop언어(객체지향 언어)
JDK 1.8이후 함수형 언어 기능도 포함한다.
->haskell, scalla 등
python,js도 함수형 언어의 기능을 갖고 있다.
함수(메서드)를 간단한 식으로 표현하는 방법을 람다식이라고 함
//일반 메서드 작성
int max(int a, int b) {
return a > b ? a: b;
}
// 람다식 작성)익명함수 사용
// 1. 메서드의 이름과 반환타입을 제거하고 ->를 블록{}앞에 추가한다.
(int a, int b) -> {
return a > b ? a : b;
}
//2. 반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능 (!! 끝에 ';' 안 붙임!!)
(int a, int b) -> a > b ? a : b
// a나 b가 반환값이 된다
//3. 매개변수의 타입이 추론 가능하면 생략 가능(대부분의 경우 생략가능)
(a,b) -> a > b ? a : b
(a) -> a * a // 생략 가능
a -> a * a
(int a) -> a * a// 이경우 생략 불가
(int i)-> System.out.println(i)
(int a, int b) -> { return a > b ? a : b; } //ok
(int a, int b) -> return a > b ? a : b; //에러
람다식은 익명 함수가 아니라 익명 객체이다.
익명 객체는 객체의 선언과 생성을 동시에 한다.
public class ex14_0 {
public static void main(String[] args) {
// Object obj = (a, b) -> a > b ? a : b //람다식. 익명 객체
Object obj = new Object() {
int max(int a, int b) {
return a > b? a: b;
}
};
int value = obj.max(3,5); //에러. object 타입에 max가 없음
//그래서 필요한 것이 함수형 인터페이스
}
}
//함수형 인터페이스 만들기
@FunctionalInterface // 붙여주기
interface MyFunction {
public abstract int max(int a, int b);
}
//구현하기
//익명클래스의 선언, 객체 생성 동시에 함
//object 대신에 함수형 인터페이스를 먼저 만들고 구현해줘야 한다!!
MyFunction f = new MyFunction() {
public int max(int a, int b) {
return a > b ? a : b;
}
}
함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음(단, 함수형 인터페이스의 메서드와 람다식 매개변수개수+반환타입 일치해야함
MyFunction f = (a,b) -> a > b ? a : b;
int value = f.max(3,5); //실제로는 람다식(익명 함수)이 호출됨
public class ex14_0 {
public static void main(String[] args) {
// Object obj = (a, b) -> a > b ? a : b //람다식. 익명 객체
MyFunction f = new MyFunction() {
public int max(int a, int b) { // 오버라이딩 - 접근제어자는 좁게 못 바꾼다(public 명시안하면 default)
return a > b? a: b;
}
};
// int value = obj.max(3,5); //에러. object 타입에 max가 없음
//그래서 필요한 것이 함수형 인터페이스
int value = f.max(3,5);
System.out.println("value="+ value);
}
}
@FunctionalInterface // 함수형 인터페이스는 단 하나의 추상 메서드만 가져야 함!!
interface MyFunction {
public abstract int max(int a, int b);
}
public class ex14_0 {
public static void main(String[] args) {
//람다식(익명 객체)를 다루기 위한 참조변수의 타입은 함수형 인터페이스로한다.
MyFunction f = (a,b) -> a > b ? a : b;// 람다식. 익명객체
// 아래의 추상 메소드인 max가 (a,b) -> a > b ? a : b; 와 맞아야함
// a,b를 넣으면 a>b 면 a, 아니면 b 반환
// 이름을 다 지워버렸으므로 반환타입, 매개변수 갯수가 같아야함(둘이 연결되기때문에)
int value = f.max(3,5);
System.out.println("value="+ value);
}
}
@FunctionalInterface // 함수형 인터페이스는 단 하나의 추상 메서드만 가져야 함!!
interface MyFunction {
public abstract int max(int a, int b);
}
@FunctionalInterface
public interface Functional_Area_1 {
void area(double x, double y, int type);
}
----------------
@FunctionalInterface
public interface Functional_Operator_3 {
double operator(double a, double b, String type);
}
---------------
@FunctionalInterface
public interface Functional_Plus_6 {
int plus(int a, int b);
}
---------------
@FunctionalInterface
public interface Functional_Search_4 {
void search(String str);
}
---------------
@FunctionalInterface
public interface Functional_Search_5 {
void searchAll();
}
public class Main_2 {
public static void main(String[] args) {
System.out.println("=== 람다식(Lambda)을 사용하지 않은 것[무명(익명)클래스를 사용한 것]");
Functional_Area_1 area_obj = new Functional_Area_1() {
@Override
public void area(double x, double y, int type) {
switch (type) {
case 1:
System.out.println("가로 "+x+", 세로 "+y+"인 사각형 면적은 : " + (x*y) );
break;
case 2:
System.out.println("밑변 "+x+", 높이 "+y+"인 삼각형 면적은 : " + (x*y*0.5) );
break;
case 3:
System.out.println("장축의 반지름 "+x+", 단축의 반지름 "+y+"인 타원형 면적은 : " + (3.141592*x*y) );
break;
default:
System.out.println("세번째 파라미터는 1 또는 2 또는 3 만 가능합니다.");
break;
}// end of switch (type)-------------------
}
};// end of Functional_Area_1 area = new Functional_Area_1()---------
area_obj.area(10.5, 5.5, 1);
// 가로 10.5, 세로 5.5인 사각형 면적은 : 57.75
area_obj.area(10.5, 5.5, 2);
// 밑변 10.5, 높이 5.5인 삼각형 면적은 : 28.875
area_obj.area(10.5, 5.5, 3);
// 장축의 반지름 10.5, 단축의 반지름 5.5인 타원형 면적은 : 181.426938
area_obj.area(10.5, 5.5, 4);
// 세번째 파라미터는 1 또는 2 또는 3 만 가능합니다.
System.out.println("\n=== 람다식(Lambda)을 사용한 것 ===");
/*
람다(Lambda) 함수는 프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous functions)를 지칭하는 용어이다.
현재 사용되고 있는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의 람다 대수이다.
람다 대수는 간단히 말하자면 수학에서 사용하는 함수를 보다 단순하게 표현하는 방법이다.
람다 대수는 이름을 가질 필요가 없다. 즉, 익명 함수 (Anonymous functions)이다.
람다식(Lambda)은 익명함수(anonymous function)을 생성하기 위한 식으로서 객체 지향 언어보다 함수 지향 언어에 가깝다.
자바에서 람다식의 사용 목적은 인터페이스에 정의된 메소드를 구현시 코딩양을 확 줄여서 간편하게 사용하는 것이 목적이다.
자바에서는 함수 단독으로는 사용할 수 없고 객체를 통해서만 사용이 가능한 형태이므로
자바에서 람다를 실행하려면 전제조건으로 먼저 FunctionalInterface(함수형 인터페이스)를 구현한 익명(무명)클래스 객체가 생성되어져 있어야만 한다.
람다는 FunctionalInterface(함수형 인터페이스)를 구현한 익명(무명)클래스 객체의 메소드로 동작하게 된다.
여기서 주의할 점은 FunctionalInterface(함수형 인터페이스)는 오로지 딱 한개만의 추상메소드로 이루어져야 한다는 것이다.
만약에 FunctionalInterface(함수형 인터페이스)에 두 개 이상의 메소드가 선언되면 자바 컴파일러는 오류를 발생시킨다.
함수형 인터페이스를 만드려면 @FunctionalInterface 어노테이션을 사용하면 된다.
*/
Functional_Area_1 lambda_area_obj = (x, y, type) -> {
switch (type) {
case 1:
System.out.println("가로 "+x+", 세로 "+y+"인 사각형 면적은 : " + (x*y) );
break;
case 2:
System.out.println("밑변 "+x+", 높이 "+y+"인 삼각형 면적은 : " + (x*y*0.5) );
break;
case 3:
System.out.println("장축의 반지름 "+x+", 단축의 반지름 "+y+"인 타원형 면적은 : " + (3.141592*x*y) );
break;
default:
System.out.println("세번째 파라미터는 1 또는 2 또는 3 만 가능합니다.");
break;
}// end of switch (type)-------------------
};
lambda_area_obj.area(10.5, 5.5, 1);
// 가로 10.5, 세로 5.5인 사각형 면적은 : 57.75
lambda_area_obj.area(10.5, 5.5, 2);
// 밑변 10.5, 높이 5.5인 삼각형 면적은 : 28.875
lambda_area_obj.area(10.5, 5.5, 3);
// 장축의 반지름 10.5, 단축의 반지름 5.5인 타원형 면적은 : 181.426938
lambda_area_obj.area(10.5, 5.5, 4);
// 세번째 파라미터는 1 또는 2 또는 3 만 가능합니다.
System.out.println("\n~~~~~~~ 람다식(Lambda) 표기방법 알아보기 ~~~~~~~~");
Functional_Operator_3 annonymous_op = new Functional_Operator_3() {
@Override
public double operator(double a, double b, String type) {
double result = 0.0;
switch (type) {
case "+":
result = a+b;
break;
case "-":
result = a-b;
break;
case "*":
result = a*b;
break;
case "/":
result = a/b;
break;
default:
System.out.println("세번째 파라미터는 + - * / 만 가능합니다.");
break;
}// end of switch(type)-----------------
return result;
}
};
double opr_result = annonymous_op.operator(20, 10, "+");
System.out.println(opr_result); // 30.0
// 1. 람다식(Lambda) 표기 기본방법
Functional_Operator_3 annonymous_op2 = (double a, double b, String type) -> {
double result = 0.0;
switch (type) {
case "+":
result = a+b;
break;
case "-":
result = a-b;
break;
case "*":
result = a*b;
break;
case "/":
result = a/b;
break;
default:
System.out.println("세번째 파라미터는 + - * / 만 가능합니다.");
break;
}// end of switch(type)-----------------
return result;
};
opr_result = annonymous_op2.operator(20, 10, "-");
System.out.println(opr_result); // 10.0
// 2. 파라미터의 타입은 생략할 수 있다.
Functional_Operator_3 annonymous_op3 = (a, b, type) -> {
double result = 0.0;
switch (type) {
case "+":
result = a+b;
break;
case "-":
result = a-b;
break;
case "*":
result = a*b;
break;
case "/":
result = a/b;
break;
default:
System.out.println("세번째 파라미터는 + - * / 만 가능합니다.");
break;
}// end of switch(type)-----------------
return result;
};
opr_result = annonymous_op3.operator(20, 10, "*");
System.out.println(opr_result); // 200.0
// 3. 실행명령문이 1개 이라면 { }; 를 생략할 수 있다.
Functional_Search_4 lambda_srch = (str) -> System.out.println("회원들중 \""+ str +"\"님을 조회합니다.");
lambda_srch.search("이순신");
// 회원들중 "이순신"님을 조회합니다.
// 4. 파라미터의 개수가 1개일때는 파라미터를 감싸는 소괄호() 를 생략할 수 있다.
Functional_Search_4 lambda_srch2 = str -> System.out.println("회원들중 '"+ str +"'님을 조회합니다.");
lambda_srch2.search("엄정화");
// 회원들중 '엄정화'님을 조회합니다.
// 5. 파라미터의 개수가 2개 이상일 때는 무조건 소괄호() 를 꼭 기재해야 한다.
/*
Functional_Operator_3 annonymous_op4 = a, b, type -> { // () 가 없으므로 오류발생함.
double result = 0.0;
switch (type) {
case "+":
result = a+b;
break;
case "-":
result = a-b;
break;
case "*":
result = a*b;
break;
case "/":
result = a/b;
break;