->
를 구현부블록{} 앞에 추가한다.int max(int a, int b) {
return a > b ? a : b;
}
->
(int a, int b) -> {
return a > b ? a : b;
}
;
안 붙임)->
(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)
(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 조상클래스/인페명 { ... };
그러나
Object obj = new Object() {
int max(int a, int b) {
return a>b ? a:b;
}
};
int value = obj.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, 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]
MyFunction
)를 매개변수로 받는 메소드myMethod()
) 람다식을 호출하는 메소드(aMethod()
)를 만든다.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!!!!