함수형인터페이스는 추상메서드가 단 하나만 존재하는 인터페이스.

람다식은 함수형 인터페이스 기반으로 작성

@FunctionalInterface
interface Calculate{
int cal(int a, int b);
}

@FunctionalInterface 어노테이션을 붙여서 함수형 인터페이스에 부합하는지확인할 수 있다.

(컴파일타임에검사)

*static이나 default선언이 붙은 메서드의 경우 함수형 인터페이스에 영향을 끼치지는 않는다.

@FunctionalInterface
public interface Calculate{
int cal(int a, int b);

default int plus(int a, int b) { return a+b;}
static int sub(int a, int b){return a-b;}
}

인터페이스는 제네릭으로 사용 가능

 

함수형 인터페이스 종류(반환하는지, 매개변수 등에 따라 분류)

Function<T,R> T타입 인자 받고 R타입 객체 리턴

Consumer<T> T타입 인자 받고 리턴 없음

Runnable 인자도 안받고 리턴값도 없음

Predicate<T> T타입 인자 받고 결과로 boolean 리턴

Supplier<T> 인자를 받지않고 T타입 객체 리턴

[ 메소드 참조(Method Reference) ]

메소드 참조란 함수형 인터페이스를 람다식이 아닌 일반 메소드를 참조시켜 선언하는 방법이다. 일반 메소드를 참조하기 위해서는 다음의 3가지 조건을 만족해야 한다.

  • 함수형 인터페이스의 매개변수 타입 = 메소드의 매개변수 타입
  • 함수형 인터페이스의 매개변수 개수 = 메소드의 매개변수 개수
  • 함수형 인터페이스의 반환형 = 메소드의 반환형

참조가능한 메소드는 일반 메소드, Static 메소드, 생성자가 있으며 클래스이름::메소드이름 으로 참조할 수 있다. 이렇게 참조를 하면 함수형 엔터페이스로 반환이 된다. 3가지의 메소드에 대해 메소드 참조 예시를 자세히 살펴보도록 하자.

 

 

1. 일반 메소드 참조

예를 들어 위에서 보여준 Function에 메소드 참조를 적용한다고 하자. 우선 해당 메소드(length)가 위의 3가지 조건을 만족하는지 살펴보아야 한다.

  • 매개변수 없음
  • 매개변수 개수 = 0개
  • 반환형 = int

우리가 선언한 function과 String의 length 함수는 모두 매개변수가 없으며, 반환형이 int로 동일하기 때문에 String::length로 다음과 같이 메소드 참조를 적용할 수 있다.

// 기존의 람다식
Function<String, Integer> function = (str) -> str.length(); function.apply("Hello World");
// 메소드 참조로 변경 Function<String, Integer> function = String::length; function.apply
("Hello World");

또한 추가로 예시를 살펴보자. System.out.println() 메소드는 반환형이 void이며, 파라미터로 String을 받는 메소드이다. 그렇기 때문에 우리는 Consumer에 System.out.println() 메소드를 참조시킬 수 있다.

// 일반 메소드를 참조하여 Consumer를 선언한다. 
Consumer<String> consumer = System.out::println;
consumer.accept("Hello World!!");
// 메소드 참조를 통해 Consumer를 매개변수로 받는 forEach를 쉽게 사용할 수 있다.
List<String> list = Arrays.asList("red", "orange", "yellow", "green", "blue");
list.forEach(System.out::println); 
//interface Iterable<T> default void forEach(Consumer<? super T> action) 
{ Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }

2. Static 메소드 참조

Static 메소드 역시 메소드 참조가 가능하다. 예를 들어 Objects의 isNull은 반환값이 Boolean이며, 매개변수 값은 1개이고, 매개 변수가 Object이므로 Predicate로 다음과 같이 메소드 참조가 가능하다.

Predicate<Boolean> predicate = Objects::isNull; 
// isNull 함수
public static boolean isNull(Object obj) { return obj == null; }


3. 생성자 참조

생성자도 메소드 참조를 할 수 있다. 생성자는 new로 생성해주므로 클래스이름::new로 참조할 수 있다. Supplier는 매개변수가 없이 반환값만을 갖는 인터페이스이기 때문에, 매개변수 없이 String 객체를 새롭게 생성하는 String의 생성자를 참조하여 Supplier로 선언할 수 있다.

Supplier<String> supplier = String::new;

'자바' 카테고리의 다른 글

업캐스팅, 다운캐스팅  (0) 2022.07.02
불변객체,final  (0) 2022.06.28
자바프로그램의 동작,  (1) 2021.10.17
[Java]List Interface  (0) 2021.09.18
java 환경변수 3가지 셋팅  (0) 2017.05.05

+ Recent posts