(매개변수) -> 함수바디(구현부)

interface 변수 = 람다식(함수구현);           ex ) MyFunction f1 = () ->System.out.println(“출력”);

  • 객체지향언어인 자바를 함수형 언어로 사용
  • 익명 함수 (반환타입 X, 메서드 이름 X)
  • 익명 클래스의 객체임 (람다식으로 만들때 익명 클래스, 인터페이스 모두 생략)
  • 람다식(함수)에서 로컬변수(람다식을 쓰고있는 메서드에 정의된 변수)를 쓰고 싶으면 final로 설정해야 함 (but, default값이 final)   -> 메서드 안의 메서드에서 사용하려면 outer 메서드에서 그 변수를 final로 설정해야 함.
    하지만, 계산하고 싶으면 바깥메서드의 로컬변수가 아닌 class 영역에 멤버변수로 설정(∵멤버변수는 사용 가능)

▷ 익명클래스 -> 람다식

LambdaInterface f1 = new LambdaInterface() {
   
    @Override
    public void method() {
	  System.out.println("출력");
	}
}; 
		    
		
		
LambdaInterface f1 = () -> {
	System.out.println("출력");
};

▷ 로컬변수

class Outer {
	int iv = 10;		// iv
	void method() {
		int iv = 40;		// lv (기본값 : final)
		LambdaInterface f = () -> {
//		    int iv = 50; // 같은 local안에 iv 중복 X
//		    iv = 50; 	// final이라 수정 X
		    System.out.println(Outer.this.iv);		//10
		    System.out.println(this.iv);		//10
		    System.out.println(iv);			//40
		};
		f.method();
	}
       
}

  • 메서드[method()] 내의 내부클래스(인터페이스)[LambdaInterface]의 메서드가 람다식으로 구현
  • 안의 메서드[람다식-익명함수]에서 바깥메서드[method()]의 변수[iv = 40]를 사용하려면 final로 설정해야함.

람다식 생략 방법

  • 매개변수의 타입도 생략가능
  • { }안에 문장이 한 줄일 때 { }생략가능 (단, return문 일때는 { return     }; 생략)
    -> 문장이 아닌 식일경우 { return     ;} 생략 가능
  • 매개변수가 하나일 때 ( ) 생략가능

● 함수형 인터페이스(@functionalInterface)  - 람다식을 다루기 위한 인터페이스, 단 하나의 추상메서드만 선언되어 있음  - 구현시 그 하나의 메서드를 구현하는 것임 (람다식과 인터페이스의 메서드가 1:1 연결)  - 일반 인터페이스처럼 디폴트 메서드와 static 메서드도 갖을 수 있음(추상메서드만 하나면 됨)

@FunctionalInterface
interface MyFunction {
    void print();
}

public class lambdaEx {
	public static void main(String[] args) {
       		MyFunction f1 = () -> System.out.println("출력");	// 구현
        	f1.print();		// 실행
	}

}

function 패키지 : 함수형 인터페이스를 미리 구현

1. 매개변수나 반환값이 1개이하 함수형 인터페이스

함수형 인터페이스 메서드 매개변수 리턴값
java.lang.Runnable void run() . .
Supplier<.T> T get() .
Cousumer<.T> void accept(T t) .
Function<T, R> R apply(T t) <.T>
Predicate<.T> boolean test(T t) (Boolean)
UnaryOperator</span> T apply(T t)
  • Function 인터페이스 : 주로 매개값(T)을 리턴값(R)으로 매핑(타입변환)할 경우 사용
  • Predicate 인터페이스 : Function의 변형, Boolean값을 반환
  • Operator 인터페이스 : Function의 변형, 매개변수타입과 리턴값의 타입이 같음.

2. 매개변수가 2개인 함수형 인터페이스

함수형 인터페이스 메서드 매개변수 리턴값
BiCousumer<T, U> void accept(T t, U u) <T, U> .
BiFunction<T, U, R> R apply(T t, U u) <T, U>
BiPredicate<T, U> boolean test(T t, U u) <T, U> (Boolean)
BinaryOperator<T, T> T apply(T t, T t) <T, T>
Consumer<String> c = (t) -> System.out.println(t+8);		

                       

Consumer<T> c = new Consumer() { 
    void accept(T t) {
        System.out.println(t+8); 
    }
};
=======================================1===============================
printString(t -> t.getName());

               
               
Function<Student, String> f = t -> t.getName();
printString(f);
    
               

Function<Student, String> f = new Function<Student, String>() {

    @Override
    public String apply(Student t) {
        return t.getName();
    }
};
printString(f);

  
=======================================2===============================  
printString(t -> t.getName());

                

printString(new Function<Student, String>() {

    @Override
    public String apply(Student t) {
        return t.getName();
    }
});


private static void printString(Function<Student, String> f) {
    System.out.println(f.apply(t));
}

● andThen(), compose()

  • Function 인터페이스의 default 메서드
  • 두개의 함수식 인터페이스를 순차적으로 연결해 실행, 첫번째 리턴 값을 두번째 매개값으로 이용하여 최종값 도출.
  • andThen() : 앞→뒤                 ex) f1<T, R>.andthen(f2<R, V>)   == T,R -> R,V [최종 V리턴타입] (f1 -> f2)
  • compose() : 앞←뒤                ex) f1<T, R>.compose(f2<V, T>)   == V,T -> T,R [최종 R리턴타입] (f2 -> f1)

● and(), or(), negate()

  • Predicate 인터페이스의 default 메서드
  • and() : && 대응 -> 두 Predicate가 모두 true면 최종 true 리턴        ex) p12 = p1.and(p2);
  • or() : || 대응 -> 두 Predicate 중 하나만 true면 최종 true 리턴          ex) p12 = p1.or(p2);
  • negate() : ! 대응-> Predicate 결과가 true이면 false, false이면 true    ex) p12 = p1.negate();

메서드 참조

  • 람다식에서 불필요한 매개변수를 제거하는 목적 (함수형 인터페이스의 타입을 보고 매개변수의 타입을 충분히 알아 낼 수 있음)
  • 함수형 인터페이스와 사용할 메소드의 매개변수 갯수와 타입이 같아야만 사용 가능. 제너릭 참조인 경우에만 사용 가능

static 메서드 참조

IntBinaryOperator operator = (x, y) -> Calculator.staticMethod(x, y);
                       
operator = Calculator::staticMethod;

인스턴스 메서드 참조

Calculator obj = new Calculator();
operator = (x, y) -> obj.instanceMethod(x, y);
                       
operator = obj::instanceMethod;

매개변수의 메서드 참조 (a의 타입 :: 메서드)

ToIntBiFunction<T, U> function = T :: int compareToIgnoreCase(U);

ToIntBiFunction<String, String> function = (a,b) -> a.compareToIgnoreCase(b);
			   
function = String :: compareToIgnoreCase;

생성자와 배열

// 생성자
Function<Integer, Myclass> f = (i) -> new MyClass(i);	
                       
Function<Integer, Myclass> f = MyClass::new;	


// 배열
Function<Integer, int[]> f = x -> new int[x];
                       
Function<Integer, int[]> f = int[]::new;