본문 바로가기
Java/Java

[Java] 함수형 인터페이스(Functional Interfaces)

by 기록하는_사람 2022. 10. 20.

함수형 인터페이스(Functional Interfaces)

📌 함수형 인터페이스(Functional Interfaces)

: 추상 메소드 하나만 가지는 인터페이스.

 

📌 람다식은 함수형 인터페이스를 기반으로만 작성할 수 있음.

 

📌 @FunctionalInterface

: 함수형 인터페이스에 부합하는 지 확인하기 위한 어노테이션 타입. 

 

📌 static, default 선언은 함수형 인터페이스 정의에 영향을 주지 않음. 

 

📌 제네릭으로 정의된 함수형 인터페이스를 대상으로 람다식 작성 가능.

 

📄 GenericLambdaTest.java

package lambda;

@FunctionalInterface
interface Calculate <T> {  // 제네릭으로 정의된 함수형 인터페이스.
	T cal(T a, T b);
}

public class GenericLambdaTest {

	public static void main(String[] args) {
		Calculate<Integer> ci = (a, b) -> a + b;
		System.out.println(ci.cal(5, 2));  // 7

		Calculate<Double> cd = (a, b) -> a + b;
		System.out.println(cd.cal(5.1235, 2.4321));  // 7.5556
	}

}

 

📌 정의되어 있는 함수형 인터페이스

Predicate<T> boolean test(T t)
Supplier<T> T get( )
Consumer<T> void accept(T t)
Function<T, R> R apply(T t)

 

Predicate<T>

📌 boolean test(T t); 추상 메소드 존재.

: 전달된 인자를 판단해 true, false 반환. 

 

📌 Predicate<T>를 구체화, 다양화 한 인터페이스

IntPredicate boolean test(int value)
LongPredicate boolean test(lona value)
DoublePredicate boolean test(double value)

 

📄 PredicateTest.java

package lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class PredicateTest {
	public static <T> void show(Predicate<T> p, List<T> li) {
		for(T n : li) {
			if(p.test(n)) {
				System.out.print(n + " ");
			}
		}
	}

	public static void main(String[] args) {
		List<Integer> li1 = Arrays.asList(1, 3, 4, 8, 10, 11);  
		show(n -> n%2 != 0, li1);  // 홀수만 출력. // 1 3 11 
		
		System.out.println();
		List<Double> li2 = Arrays.asList(-3.5, 6.2, 5.1, -8.9);
		show(n -> n > 0.0, li2);  // 0.0보다 큰 수만 출력. // 6.2 5.1 
	}

}

 

Supplier<T>

📌 T get( );  추상 메소드 존재.

: 무언가를 반환할 때 사용. 

 

📌 Supplier<T>를 구체화, 다양화 한 인터페이스

IntSupplier int getAsInt( )
LongSupplier long getAsLong( )
DoubleSupplier double getAsDouble( )
BooleanSupplier boolean getAsBoolean( )

 

📄 SupplierTest.java

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;

public class SupplierTest {
	public static List<Integer> mkIntList(Supplier<Integer> s, int n) {
		List<Integer> li = new ArrayList<>();
		
		for(int i = 0; i < n; i++) {
			li.add(s.get());
		}
		
		return li;
	}
	
	public static void main(String[] args) {
		Supplier<Integer> sp = () -> {
			Random rand = new Random();
			return rand.nextInt(100);
		};
		
		List<Integer> li = mkIntList(sp, 10);  // [27, 69, 95, 95, 6, 92, 53, 27, 84, 62]
		System.out.println(li);
		
		li = mkIntList(sp, 20);
		System.out.println(li);  // [93, 84, 39, 25, 66, 8, 13, 49, 98, 94, 15, 54, 18, 61, 74, 49, 13, 5, 44, 47]
	}

}

 

Consumer<T>

📌 void accept(T t); 추상 메소드 존재.

: 반환 이외의 다른 결과를 보일 때 사용. 

 

📌 Consumer<T>를 구체화, 다양화 한 인터페이스

IntConsumer void accept(int value)
ObjIntConsumer<T> void accept(T t, int value)
LongConsumer void accept(long value)
ObjLongConsumer<T> void accept(T t, long value)
DoubleConsumer void accept(double value)
ObjDoubleConsumer<T> void accept(T t, double value)
BiConsumer<T, U> void accept(T t, U u)

 

📄 ConsumerTest.java

package lambda;

import java.util.function.Consumer;

public class ConsumerTest {

	public static void main(String[] args) {
		Consumer<String> c = s -> System.out.println(s);
		c.accept("hi");  // hi
		c.accept("Nice to meet you");  // Nice to meet you
	}

}

 

Function<T, R>

📌 R apply(T t); 추상 메소드 존재.

: 전달 인자와 반환 값이 모두 존재할 때. 

 

📌 Function<T, R>를 구체화, 다양화 한 인터페이스

IntToDoubleFunction double applyAsDouble(int value)
DoubleToIntFunction int applyAsInt(double value)

 

💡 인터페이스 규칙

- 반환형과 매개변수형이 동일한 인터페이스 : Operator로 끝남.

- 매개변수가 하나인 인터페이스 : 앞에 Unary가 붙음. 

     

📄 FunctionTest.java

package lambda;

import java.util.function.Function;

public class FunctionTest {

	public static void main(String[] args) {
		Function<Double, Double> cti = d -> d * 0.393701;
		Function<Double, Double> itc = d -> d * 2.54;
		
		System.out.println("1cm = " + cti.apply(1.0) + "inch");  // 1cm = 0.393701inch
		System.out.println("1inch = " + itc.apply(1.0) + "cm");  // 1inch = 2.54cm
	}

}

 

 

댓글