JAVA4_01_람다식
람다식 Lambda Expression
정의
- 함수(메소드)를 간단한 식(expression)으로 표현하는 방법
- 익명 함수, 이름이 없는 함수, anonymous function
함수와 메소드의 차이
- 근본적으로 동일
- 함수는 일반적 용어, 메소드는 객체지향개념 용어
- 함수는 클래스에 독립적, 메소드는 클래스에 종속적
✨작성 방법
- 메소드명과 반환타입 제거하고,
->
를 구현부블록{} 앞에 추가한다.
int max(int a, int b) {
return a > b ? a : b;
}
->
를 구현부블록{} 앞에 추가한다.int max(int a, int b) {
return a > b ? a : b;
}
->
(int a, int b) -> {
return a > b ? a : b;
}
- 반환값이 있는 경우 : 식이나 값만 적고 return문 생략 가능(끝에
;
안 붙임)
->
(int a, int b) -> a > b ? a : b
- 매개변수의 타입이 추론가능하면 생략 가능(대부분 생략가능)
->
(a, b) -> a > b ? a : b
주의사항
- 매개변수가 하나인 경우 : 괄호() 생략 가능(타입이 없을 때만)
a -> a * a //(O)
(int a) -> a * a //(O)
(a) -> a * a //(O)
int a -> a * a //(X)
- 구현부블록{} 안의 문장이 하나일 때 : 괄호{} 생략 가능(
;
안 붙임)
(int i) -> System.out.println(i)
- return문 생략하지 않을 때 : 괄호{} 생략 불가
(int a, int b) -> { return a > b ? a : b } //(O)
(int a, int b) -> a > b ? a : b //(O)
(int a, int b) -> return a > b ? a : b //(X)
예
//메소드 -> 람다식으로 바꿔보자
//1.
int max(int a, int b) {
return a > b ? a : b;
}
//->
(a, b) -> a>b ? a:b
//2
void printVar(String name, int i) {
System.out.println(name+ "="+i);
}
//->
(name, i) -> System.out.println(name+"="+i)
//3
int square(int x) {
return x*x;
}
//->
x -> x*x
//4
int roll() {
return (int)(Math.random()*6);
}
//->***매개변수가 없을 땐 괄호()생략 안됨!!
() -> (int)(Math.random()*6)
람다식은 익명 객체!!
-
✨✨람다식은 익명 함수가 아니라 익명 객체이다!!
-
위에 예시로 쓴 람다식은 아래와 같다.
new Object() {
int max(int a, int b) {
return a > b ? a : b;
}
}
-
따라서 ✨✨참조변수로 다뤄야 한다!!
-
익명클래스 선언, 객체 생성 동시에 하는 방법
new 조상클래스/인페명 { ... };
✨✨람다식은 익명 함수가 아니라 익명 객체이다!!
위에 예시로 쓴 람다식은 아래와 같다.
new Object() {
int max(int a, int b) {
return a > b ? a : b;
}
}
따라서 ✨✨참조변수로 다뤄야 한다!!
익명클래스 선언, 객체 생성 동시에 하는 방법
new 조상클래스/인페명 { ... };
그러나
Object obj = new Object() {
int max(int a, int b) {
return a>b ? a:b;
}
};
int value = obj.max(3, 5);
- 📢📢문제 발생!!
-> 1. 타입캐스팅을 해야하는데, 어떻게 해야하는가?
-> 2. The target type of this expression must be a functional interface.
이를 해결해주는 게 함수형 인터페이스!!
즉, ✨✨✨함수형 인터페이스 타입의 참조변수로 람다식을 다뤄야 한다!!
함수형 인터페이스
- ✨단 하나의 추상 메소드만 선언된 인터페이스
1.
@FunctionalInterface
interface MyFunction {
public abstract int max(int a, int b);
}
2.
+ 익명클래스로 직접 구현
MyFunction f = new MyFunction() {
public int max(int a, int b) {
return a > b ? a : b;
}
};
//**(O) MyFunction에 max()가 있으니까!
int value = f.max(3, 5);
+ 람다식
MyFunction f = (a, b) -> a > b? a : b;
int value = f.max(3, 5);
//실제로는 람다식(익명함수)이 호출됨
@FunctionalInterface
interface MyFunction {
public abstract int max(int a, int b);
}
MyFunction f = new MyFunction() {
public int max(int a, int b) {
return a > b ? a : b;
}
};
//**(O) MyFunction에 max()가 있으니까!
int value = f.max(3, 5);
MyFunction f = (a, b) -> a > b? a : b;
int value = f.max(3, 5);
//실제로는 람다식(익명함수)이 호출됨
ex14_00
class Ex14_00 {
public static void main(String[] args) {
//익명클래스로 직접 구현
MyFunction2 f = new MyFunction2() {
@Override
public int max(int a, int b) { //***public!!
return a>b? a:b;
}
};//MF
int value = f.max(3, 5);
System.out.println("value= "+value);
//람다식***
MyFunction2 f2 = (a, b) -> a>b? a:b;
int value2 = f2.max(3, 5);
System.out.println("value2= "+value2);
}//main
}
@FunctionalInterface
interface MyFunction2{
public abstract int max(int a, int b);
}
value= 5
value2= 5
함수형 인페 & 람다식을 활용한 Comparator
- Comparator도 FunctionalInterface로, 하면 된다?
점점 작성하는 것이 너무 귀찮아져서 그만....ㅎㅎ
Comparator, Comparable, sort()
ex14_001
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Ex14_001 {
public static void main(String[] args) {
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
// Collections.sort(list, new Comparator<T>() {
// public int compare(String s1, String s2) {
// if(s1 instanceof Comparable && s2 instanceof Comparable) {
// Comparable c1 = (Comparable) s1;
// Comparable c2 = (Comparable) s2;
// return s2.compareTo(s1); //역순
// }
// return -1;
// }
// });
//이 방식은 자꾸 에러나서 못하겠다 ㅠㅠㅠ
System.out.println("list = "+list);
}
}
//기본적으로 이렇게 되어있어, 아래가 없어도 작동한다!
@FunctionalInterface
interface Comparator<T>{
public abstract int compare(T o1, T o2);
}
list = [ddd, bbb, abc, aaa, aaa]
ex11_07 추가
import java.util.Arrays;
import java.util.Comparator;
public class Ex11_07 {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr, (s1, s2) -> s2.compareTo(s1));
System.out.println("strArr = "+Arrays.toString(strArr));
Arrays.sort(strArr, new Descending());
//이번엔 직접 만든 기준을 담은 객체를 호출한다.+역순
System.out.println("strArr = "+Arrays.toString(strArr));
}
}
//마찬가지!! 아래가 없어도 잘 작동함
@FunctionalInterface
interface Comparator1{
public abstract int compare(Object o1, Object o2);
}
//둘다 되는데 뭐가 맞는지 모르겠다.
@FunctionalInterface
interface Comparator1<T>{
public abstract int compare(T o1, T o2);
//기존의 compare()를 역순을 배출하는 메소드로 오버라이딩하기
//따라서 compare()를 갖고 있는 Comparator를 구현해야 한다.
class Descending implements Comparator{
public int compare(Object o1, Object o2) {
//Comparable이 o1, o2의 조상타입클래스 또는 구현된인터페이스라면
//이 문제에선, String implements Comparable 이므로 true
//왜 Comparable?? : compareTo()를 쓰려고
if(o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
return c1.compareTo(c2) * -1;
// return c2.compareTo(c1);
}
return -1;
//비교대상이 Comparable을 구현한 클래스가 아니면 비교할 수 없기에
//참고로 String은 Comparator를 구현하지 않았다!! Comparable만!!!
}
}
strArr = [Dog, cat, lion, tiger]
strArr = [cat, Dog, lion, tiger]
strArr = [tiger, lion, cat, Dog]
strArr = [tiger, lion, cat, Dog]
함수형 인터페이스
함수형 인터페이스타입의 매개변수
1.
- 람다식이 있는 함수형인페(
MyFunction
)를 매개변수로 받는 메소드 - 람다식에 이름을 붙여(
myMethod()
) 람다식을 호출하는 메소드(aMethod()
)를 만든다.
2.
- 람다식을 호출하는 메소드의 매개변수에 람다식을 작성한다.
함수형 인터페이스타입의 반환타입
- 람다식이 있는 함수형인페(
MyFunction
)가 반환타입인 메소드 - 그 메소드(
myMethod()
) 안에서 반환타입에 람다식을 작성한다.
ex14_01
public class Ex14_01 {
public static void main(String[] args) {
//1. 익명클래스로
MyFunction f1 = new MyFunction() {
@Override
public void run() {
System.out.println("f1.run!");
}
};
f1.run();
//2. 람다식으로
MyFunction f2 = () -> System.out.println("f2.run!!");
f2.run();
//3. 함수형인페를 매개변수로 삼고, 람다식을 호출하는 메소드
MyFunction f3 = () -> System.out.println("f3.run!!!");
execute(f3); //이 두줄을 줄이면
execute(() -> System.out.println("f3.run!!!"));
//4. 함수형인페가 반환타입, 람다식을 뱉어내는 메소드
MyFunction f4 = getMyFunction();
f4.run();
//이렇게 바로도 된다!
getMyFunction().run();
}//main
static void execute(MyFunction f) {
f.run(); //람다식을 호출하는 메소드
}
static MyFunction getMyFunction() {
// MyFunction f = () -> System.out.println("f4.run!!!!");
// return f;
return () -> System.out.println("f4.run!!!!");
}
}
@FunctionalInterface
interface MyFunction{
void run();
}
f1.run!
f2.run!!
f3.run!!!
f3.run!!!
f4.run!!!!
f4.run!!!!
Ref
Author And Source
이 문제에 관하여(JAVA4_01_람다식), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@lecharl/JAVA401저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)