자바/자바 입문 공부일지

자바 기초 공부 일지 48. 함수형 인터페이스 Predicate<T>, Supplier<T>, Consumer<T>, Function<T, R>

Tomitom 2022. 11. 4. 12:34
반응형

 

공부에 참고한 페이지 : https://m.blog.naver.com/zzang9ha/222087024556

 

[Java/자바] - Function<T, R> interface

Function<T, R> interface 안녕하세요, 이번시간에 알아볼 함수형 인터페이스는 Function<T,...

blog.naver.com

 

 자바에는 미리 정의되어 있는 함수형 인터페이스도 있고, 

미리 정의되어 있는 함수형 인터페이스를 사용하는 표준 메소드 및 클래스도 정의되어 있습니다.

정의되어 있는 인터페이스를 사용하면 보다 편리하게 코드를 구현할 수 있습니다. 

함수형 인터페이스는 @FunctionalInterface 어노테이션 사용해서 함수형 인터페이스의 조건에 부합하는지 검사하는 것이 좋습니다. 

 

 

default boolean removeIf(Predicate<? super E> filter)

   → Collection<E> 인터페이스에 정의되어 있는 디폴트 메소드

 

removeIf 는 그 중 한 가지입니다. 

제네릭 기반의 함수형 인터페이스 Predicate 예요. 

Predicate 인터페이스의 추상 메소드는 자바에서 다음과 같이 정의해 두었습니다. 

   boolean test(T t);

 

Predicate 는 인자 하나를 가져다가 true 혹은 false를 반환하기 위해서 사용하는 것입니다.

즉 해당 메소드는 미리 정의해 두었으므로 Predicate라는 이름만으로 통합니다. 

 


 

● 상기의 예시처럼 java.util.funtion 의 패키지로 묶어져 있는 함수형 인터페이스들은 다음과 같습니다.

 

Predicate<T>   boolean test(T t)      전달 인자를 근거로 참 또는 거짓을 반환

Supplier<T>   T get()          메소드 호출 시 무엇인가를 제공함

Consumer<T>   void accept(T t)     무엇인자를 받아 들이기만 함

Function<T, R>   R apply(T t)       입출력 출력이 있음(수학적으로는 함수)

 

위 함수형 인터페이스들을 하나씩 살펴볼게요. 

 


(1) Predicate<T>

 

위 인터페이스에는 추상메소드가 존재합니다. 

boolean test(T t);  // 전달된 인자를 대상으로 True, False 를 판단할 때

즉 조건식을 표현하는데 사용합니다. 매개변수는 한 개고 반환 타입은 boolean 이에요. 

 

Predicate<T> 
    boolean test(T t);
- T를 인자로 받고, Boolean형을 리턴한다.

 

매개변수로 받은 값이 양수인지 음수인지 확인하는 예제를 살펴보겠습니다. 

매개변수 i 를 선언하고, i가 0보다 크면 양수, 0보다 작으면 음수가 됩니다. 

 

package day20;

import java.util.function.Predicate;

public class Test01 {

	public static void main(String[] args) {
		
		Predicate<Integer> isWhat = i -> i > 0 ; 
		System.out.println(isWhat.test(-1));
		System.out.println(isWhat.test(0));
		System.out.println(isWhat.test(1));
	}

}

 

 

이번에는 이를 활용해서 홀수 중 최댓값과 짝수 중 최댓값을 구하는 코드를 구현해볼게요. 

 

package day20;


import java.util.*; 
import java.util.function.*; // 함수형 인터페이스들이 있음 


public class FuncInter {
	
	public static int getMax(Predicate<Integer>p, List<Integer>list){
		int max = 0;
		
		for(int n : list) {
			if(p.test(n)) {
				if(max < n) {
					max = n;
				}
			}
		}
		return max;
	}

	public static void main(String[] args) {

		List<Integer> iList = Arrays.asList(1,2,3,4,5,6,7,8,9);
		
		int m; 
		int e;
		m = getMax(n -> n%2 == 1, iList);
		e = getMax(n -> n%2 == 0, iList);
		System.out.println("홀수 중 최댓값: " + m );
		System.out.println("짝수 중 최댓값: " + e );

	}

}

 


 Predicate<T>는 boolean test(Integer t) 메소드 정의에 해당하는 람다식을 작성해서 매개변수로 전달해야 합니다.

 

 


 

(2) Supplier<T> 

 

위 인터페이스에는 다음과 같은 추상메소드가 있습니다. 

T get(); // 매개변수가 없고, 단순히 무엇인가를 반환할 때

즉 매개변수를 받지 않고, 단순히 무엇인가를 반환하는 추상 메소드입니다. 


Supplier<T>
    T get();
- T를 리턴합니다.

 

단순한 예제를 통해 확인해볼게요. 

package day20;

import java.util.function.Supplier;

public class Test01 {

	public static void main(String[] args) {
		Supplier<String> helloSupplier = () -> "Hello ";
		System.out.println(helloSupplier.get() + "World");
	}
}

 


(3) Consumer<T>

 

위 인터페이스에는 다음과 같은 메소드가 있습니다. 

void accept(T t);   // 전달된 인자 기반으로 '반환' 이외의 다른 결과를 보일 때
즉, 전달된 인자 T를 가지고 어떠한 결과를 보여야 할 때 사용할 수 있습니다. (소모한 뒤 리턴하지 않습니다.) 

 

Consumer<T> 
void accept(T t);
- T를 인자로 받고, 이를 소모한다.(리턴 X)

 

이것에 대한 예제를 통해 알아볼게요. 

 

package day20;

import java.util.function.Consumer;

public class Test01 {
	public static void main(String[] args) {
	Consumer<String> print = new Consumer<String>() {
		
		@Override
		public void accept(String t) {
			System.out.println(t);
		}
	};
	
	Consumer<String> print2 = t -> System.out.println(t);
	
	print.accept("Hello!");
	print2.accept("Hello!");
	}
}

 


(4) Function<T, R>

 

위 인터페이스에는 다음과 같은 메소드가 있습니다. 

R apply(T t);   // 전달 인자와 반환 값이 모두 존재할 때

즉 apply라는 메소드가 존재하고, 인자로는 어떤 타입의 제네릭 T인자를 받고 R제네릭을 리턴합니다. 

 

Function<T, R>
R apply(T t);

- T를 인자로 받고, R을 리턴한다.

 

아래 예제를 통해서 확인해보겠습니다. 

 

package day20;

import java.util.function.Function;

public class Test01 {
	public static void main(String[] args) {
		Function<String, Integer> toInt = t -> Integer.parseInt(t);
		
		Integer number = toInt.apply("100");
		System.out.println("number: " + number);
	}
}

 

 
 

 

 

반응형