Programing Language/JAVA

JAVA 기본 함수형 인터페이스 정리

칼쵸쵸 2020. 8. 16. 22:12

자바가 기본적으로 제공해주는 인터페이스

입출력 값의 유무, 사용기능등에 따라서 다양한 함수형 인터페이스들을 사용 할 수 있다.

 

기본적인 구현 

import java.util.function.Function;

public class Plus implements Function<Integer, Integer>{

	@Override
	public Integer apply(Integer t) {
		
		return t+1;
	}

}

 

함수형 인터페이스를 사용 할 시 본래는 클래스를 함수형 인터페이스를 구현하는 형식으로 사용한다.

위의 예제는 Function이라는 기본제공 함수형 인터페이스를 사용하여 Plus라는 클래스를 생성하는 예제이다.

이는 메서드가 한개인 함수형 인터페이스이므로 람다식을 써서 구현 할 수 있다.

람다식을 통해 구현 할 시 클래스 파일을 새로 만들 필요가 없으며 정해진 함수 원하는 부분에 구현하여 객체로 표현할 수 있게 된다.

이를 통해 함수형 프로그래밍을 가능하도록 한다.

 

 

Function<T,R>

public static void main(String[] args) {
	Function<Integer, Integer> Plus = (a)-> a+3;
	Function<Integer, Integer> Multiple = (a)-> a*3;
	Function<Integer, Integer> MultiplePlus = Plus.andThen(Multiple);
	Function<Integer, Integer> MultiplePlus2 = Plus.compose(Multiple);
       
	System.out.println(Plus.apply(1)); //1+3
	System.out.println(Multiple.apply(1)); //1*3
	System.out.println(MultiplePlus.apply(1)); //(1+3)*3
	System.out.println(MultiplePlus2.apply(1)); // (1*3)+3
}

 

Function<T,R> : 하나의 입력값과 하나의 출력값

 

T와 R에서 입력과 출력의 형태를 정의 할 수 있다.

이렇게 만들어진 함수는 Compose와 andThen을 활용해서 구현된 함수끼리 연결 할 수 있다.

 

andThen : 본 함수를 먼저 실행한 후 해당 값을 파라미터 함수를 실행한다.

Compose는 : 파라미터 함수를 먼저 실행하고 해당값으로 본 함수를 실행한다.

 

apply를 통해 실행한다.

 

 

Consumer<T>

public static void main(String[] args) {
	Consumer<Integer> Print1 = (i) -> System.out.println("in");
	Consumer<Integer> Print2 = (i) -> System.out.println("out");
	Consumer<Integer> Print3 = Print1.andThen(Print2);
	
    Print1.accept(1); //in
	Print2.accept(1); //out
	Print3.accept(1); //in out
					  
}

 

Consumer<T>: 하나의 입력값 출력 없음

 

입력값은 존재하나 출력값은 존재하지 않는 함수이다.

 

Accept를 통해 실행하며 andThen을 통해 함수를 조합 할 수 있다.

 

 

Supplier<T>

public static void main(String[] args) {
	Supplier<Integer> Sup = ()->3;
	System.out.println(Sup.get());
}

 

Supplier<T> : 입력값은 없고 출력값만 존재 한다.

 

get을 통해 실행하며 다른 함수와 조합 할 수 없다.

 

 

Runnable

public static void main(String[] args) {
	Runnable a = ()->System.out.println("run");
	a.run(); //run
}

 

Runnable : 입력값도 없고 출력값도 없다.

 

다른 함수와 조합 할 수 없다.

 

위의 4개의 함수형 인터페이스를 정리하면 다음과 같다.

 

  출력 O 출력 X
입력 O Function<T,R> Consumer<T>
입력 X Supplier<T> Runnable

 

* 입력값이 존재하는 경우 함수를 조합 할 수 있다.

 

 

 

BiFunction<T, U, R>

public static void main(String[] args) {
	BiFunction<Integer, Integer, Integer> Plus = (a,b) -> a+b;
	System.out.println(Plus.apply(1, 2)); //1+2
}

 

BiFunction<T,U,R> : 두개의 입력값 하나의 출력값

T,U 에 입력값의 형태를 정의 하며 이를 R로 리턴하는 형태의 함수형 인터페이스이다.

 

apply를 통해 실행한다.

 

 

Predicate<T>

public static void main(String[] args) {
	Predicate<Integer> Pre1 = (t) -> {
		if(t>0)
		{
			return true;
		}
		else {
			return false;
		}
	};
	
	Predicate<Integer> Pre2 = (t) -> {
		if(t<2)
		{
			return true;
		}
		else {
			return false;
		}
	};

	Predicate<Integer> Pre3 = Pre1.and(Pre2);
	Predicate<Integer> Pre4 = Pre1.or(Pre2);
	Predicate<Integer> Pre5 = Pre1.negate();
	
	System.out.println(Pre1.test(1)); //true
	System.out.println(Pre1.test(-1)); //false
	
	System.out.println(Pre2.test(1)); //true
	System.out.println(Pre2.test(3)); //false

	System.out.println(Pre3.test(1)); //true
	System.out.println(Pre3.test(4)); //false
	
	System.out.println(Pre4.test(4)); //true
	System.out.println(Pre4.test(-1)); //true
	
	System.out.println(Pre5.test(1)); //false
}

 

Predicate<T> : 입력값 T에 대해서 Test를 수행하여 Boolean값을 출력한다.

 

Test를 통해 실행하며

And,Or을 통해 다른 Predicate와 조합이 가능하며

Negate를 통해 값을 반대로 리턴 할 수 있다.

 

 

UnaryOperator<T>

public static void main(String[] args) {
	UnaryOperator<Integer> Plus = (num) -> num+1;
	System.out.println(Plus.apply(1));
}

 

UnaryOperator<T> : Function의 특수한 형태로 입력값과 출력값의 타입이 동일한 경우 사용한다.

 

Function과 같은 기능을 가지고 있다.

 

 

BinaryOperator<T>

public static void main(String[] args) {
	BinaryOperator<Integer> Plus = (a,b) -> a+b;
	System.out.println(Plus.apply(1,2));
}

 

BinaryOperator<T> : BiFunction의 특수한 형태로 입력값과 출력값의 타입이 동일한 경우 사용한다.

 

BiFunction과 같은 기능을 가지고 있다.