JAVA 8+ 함수형 인터페이스, Predicate

TopOfTheHead·2026년 4월 10일

자바 ( JAVA )

목록 보기
22/28

함수형 인터페이스( Functuional Interface )
추상메소드가 오직 1개만 정의된 인터페이스
인터페이스 구현체일급객체로서 생성하기 위해 추상메소드를 1개로 제한

함수형 인터페이스를 통해 JAVA에서 함수형 프로그래밍이 가능.

ex ) Runnable 인터페이스의 경우에도 오직 1개의 추상메서드 ( run() )만 존재하므로, 함수형 인터페이스

인터페이스를 구현한 구현클래스객체없이도 인터페이스익명클래스 또는 람다식을 통해 인터페이스 구현체를 생성
▶ 단 인터페이스구현메소드가 1개인 함수형 구현메소드이어야 한다

JAVA 8부터 Interfacestatic 메소드 , default 메소드를 포함할 수 있는데, 해당 메소드를 같이 포함해도 함수형 인터페이스로서 기능할 수 있다.
static 메서드 , default 메서드자식클래스에서 반드시 구현해야하는 추상메소드가 아니므로
인터페이스 - Default Method

  • 함수형 인터페이스추상 메서드를 오직 하나만 설정하는 이유?
    JAVA에서 함수형 프로그래밍을 수행하는 경우 인터페이스 구현체일급객체 특성을 이용하여 추상메서드함수를 정의하고 변수로서 전달하는 매개체 역할을 수행
    ▶ 이로 인해 추상메서드는 오직 하나로 정의하여 해당 추상메서드메서드 오버라이딩을 통해 함수 기능을 작성한 인터페이스 구현체변수로 간주하여 프로그래밍을 수행

  • @FunctionalInterface
    함수형 인터페이스명시적으로 @FunctionalInterface를 명시.
    추상메서드가 2개 이상되는 실수를 컴파일 단계에서 방지 가능.
// 명시적으로 표현
@FunctionalInterface
interface Calculator{
	int calculate(int a, int b);
}

인터페이스 / 추상클래스가 직접 구현체를 만들 수 없는 이유?
추상메서드실행 로직을 정의할 수 없으므로 new를 통해 인터페이스 또는 추상클래스구현체를 생성할 수 없음.
▶ 이로 인해, 익명클래스를 통해 추상메서드실행 로직을 정의하는 경우 인터페이스 객체를 직접 생성할 수 있음.

 @FunctionalInterface
 public interface Ainterface{
 	void a(); // 추상메서드   
 }

인터페이스 정의 시 추상메서드실행 로직을 작성할 수 없어 인터페이스 자체로 구현체를 생성할 수 없다.

Ainterface concrete = new Ainterface(
 	@Override
    public void a(){
    	// 실행로직
    }
 );

▶ 다음처럼 추상메서드메서드 오버라이딩new를 통해서 interface 구현체를 직접 생성할 수 있음,

 Ainterface concrete = () -> {
    // 실행로직 
 };

람다 표현식으로 축약해서 구현할 수 있음

함수형 인터페이스 구현체를 생성하는 방법
인터페이스 구현체추상메서드로직을 정의해야 구현체를 생성할 수 있다.
익명클래스 / 람다식을 통해 추상메서드메서드 오버라이딩하면서 인터페이스 구현체 생성

。기존 함수형 인터페이스 구현체 생성 시 인터페이스 구현 클래스를 별도로 정의 및 구현체 객체를 생성해서 업캐스팅을 통해 구현하는 단점이 존재.
▶ 한번만 객체로 만드는데 사용되는 클래스를 정의하는건 비효율적이므로 익명클래스 , 람다식을 통해 인터페이스 구현체 생성

  • 함수형 인터페이스 구현체익명클래스를 통해 생성하여 사용
    익명 클래스 : 일회용으로 생성되는 이름 없는 클래스
// 함수형 인터페이스
@FunctionalInterface
interface IFunctional{
	int add(int a , int b); // 추상메소드 1개
	default int noRelation(int a){ // 추상메소드가 아니므로 상관 X
		return 2;
	}
}
public class Main {
	public static void main(String[] args) {
		// 익명클래스로 추상메서드의 메서드 오버라이딩을 통해 인터페이스 구현체 생성
		IFunctional addFunction = new IFunctional(){
			@Override
			public int add(int a , int b){
				return a+b;
			}
		};
		System.out.println(addFunction.add(1,2)); // 3 도출
	}
}
  • 함수형 인터페이스 구현체람다식을 활용하여 생성
    람다식을 통해 함수형 인터페이스 구현체 생성 시 매번 새롭게 생성되는 일회성코드블록으로 인터페이스 구현체가 생성되므로 해당 코드블록은 변경될 수 없으므로 불변이 보장
    병렬 프로그래밍에서 람다식이 많이 사용되는 이유

    함수형 인터페이스에 한해서만 구현체 생성 가능.
// 함수형 인터페이스
@FunctionalInterface
interface IFunctional{
	int add(int a , int b); // 추상메소드 1개
	default int noRelation(int a){ // 추상메소드가 아니므로 상관 X
		return 2;
	}
}
public class Main {
	public static void main(String[] args) {
		// 람다식으로 추상메서드의 메서드 오버라이딩을 통해 인터페이스 구현체 생성
		IFunctional addFunction = ( a,b ) ->{
			return a+b;
		}
		System.out.println(addFunction.add(1,2)); // 3 도출
	}
}

。 이때 내부 로직이 1줄인 경우 return{}를 생략할 수 있다.

IFunctional addFunction = ( a,b ) -> a+b;

자바에서 기본적으로 제공하는 함수형 인터페이스
Runnable 등이 존재.

Predicate<T> :
Predicate<Type> predicate = 람다식
。입력 값을 받아서 boolean 값을 반환하는 함수형 인터페이스

함수형 인터페이스를 요구하는 특정 List객체의 MethodPredicate를 사용 시 매개변수를 input 받아 Predicate람다식 구문을 수행 후 Boolean을 반환.
▶ 조건이 참이면 true, 거짓이면 false를 return.

。주로 Stream.filter(함수형인터페이스)의 조건을 설정하는 용도로 활용

Predicate<? super 클래스타입> :
。해당 Class type뿐만 아닌 부모 Class Type까지 적용할 수 있는 predicate를 의미.

활용례 )

private static List<Todo> todos = new ArrayList<>();
    static {
        todos.add(new Todo(todosCount++,"wjdtn747","Learn AWS", LocalDate.now().plusYears(1),false));
        todos.add(new Todo(todosCount++,"wjdtn0619","Learn DevOps", LocalDate.now().plusYears(2),true));
        todos.add(new Todo(todosCount++,"wjdtn3902","Learn FullStackDevelopment", LocalDate.now().plusYears(3),false));
    }
Predicate<? super Todo> predicate = todo -> todo.getId() == 3;
todos.removeIf(predicate);

List객체.removeIf(함수형인터페이스)predicate를 전달하여 Static List 내부의 Todo instance 가 각각 Predicate람다식에 의해 처리 후 true를 반환 시 해당 Todo instance를 Static List에서 삭제.

list객체.removeif(함수형인터페이스) :
。해당 List객체의 모든 각 요소에대해 predicate를 실시한 후 해당 조건에 대해 true이면 삭제

profile
공부기록 블로그

0개의 댓글