Contents
The Java8(자바에서 제공하는 함수형 인터페이스)
   Jul 14, 2022     7 min read

자바에서 제공하는 함수형 인터페이스

Java가 기본으로 제공하는 함수형 인터페이스

  • java.lang.function 패키지
  • 자바에서 미리 정의해둔 자주 사용할만한 함수인터페이스
    • Function<T, R>
    • BiFunction<T, U, R>
    • Consumer
    • Supplier
    • Predicate
    • UnaryOperator
    • BinaryOperator
함수형 인터페이스메소드설명
java.lang.Runnablevoid run( )매개변수도 없고, 반환값도 없음.
SupplierT get( ) T→매개변수는 없고, 반환값만 있음.
ConsumerT→ void accept(T t)Supplier와 반대로 매개변수만 있고, 반환값이 없음
Function<T, R>T→ R apply(T t) R→일반적인 함수. 하나의 매개변수를 받아서 결과를 반환
PredicateT→ boolean test(T t) boolean→조건식을 표현하는데 사용됨. 매개변수는 하나, 반환 타입은 boolean

Tip

  • 타입 문자는 ‘T’는 ‘Type’을, ‘R’은 ‘Return type’을 의미한다.

Function<T, R>

  • T 타입을 받아서 R 타입을 리턴하는 함수 인터페이스
    • R apply(T t)
  • 함수 조합용 메소드
    • compose
    • andThen
함수형 인터페이스메소드설명
Function<T, R>T→ R apply(T t) R→일반적인 함수. 하나의 매개변수를 받아서 결과를 반환
  • Function<T, R> → apply() 사용 : 인터페이스 재정의해서 표현

//입력값type: Integer, 반환값 : Integer
public class A implements Function<Integer, Integer> {
    @Override
    public Integer apply(Integer integer) {
        return integer + 10;
    }
}
public class Provided_Function {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.apply(1)); // return : 11
    }
}

이 예시는 인터페이스를 재정의(@Override)를 해서 표현한 방법

  • Funtion<T, R> → apply() 사용 : 람다식으로 표현
public class Main{
		public static void main(String[] args){
			Function<Integer, Integer> plus10 = (number) -> i + 10;
			System.out.println(plus10.apply(1)); // return 11

		}
}

이 방법은 바로 람다식으로 표현하는 방법 → 람다식 표현방법을 안다면 코드가 훨씬 짧고 간결해진다.

함수 조합용 메소드

  • 예제) compose()
public class Main{
  public static void main(String[] args){
	Function<Integer, Integer> plus10 = (number) -> i + 10;
	Function<Integer, Integer> multiply2 = (i) -> i * 2;

	Function<Integer, Integer> multiply2AndPlus10 = plus10.compose(multiplu2);
	System.out.println(multiply2AndPlus10.apply(2)); //출력 : 14
  }
}

compose() 입력값을 갖고 먼저 multiply2라는 함수를 먼저 적용한다. 그리고 결과 값을 다시 plus10에 넘겨준다.

스크린샷_2022-07-14_오후_5 23 30

스크린샷_2022-07-14_오후_5 22 55

  • 예제) andThen
public class Main{
		public static void main(String[] args){
			Function<Integer, Integer> plus10 = (number) -> i + 10;
			Function<Integer, Integer> multiply2 = (i) -> i * 2;

			System.out.println(plus10.andThen(multiply2).apply(2));
		}
}

스크린샷_2022-07-14_오후_5 25 47

스크린샷_2022-07-14_오후_5 26 07

BiFunction<T, U, R>

  • 두 개의 값(T,U)를 받아서 R타입을 리턴하는 함수 인터페이스
    • R apply(T t, U u)
함수형 인터페이스메소드설명
BiFunction<T, U, R>T, U → R apply(T t, U u) R →두 개의 매개변수를 받아서 하나의 결과를 반환

Consumer

  • T 타입을 받아서 아무값도 리턴하지 않는 함수 인터페이스
    • void Accept(T t)
  • 함수 조합용 메소드
    • andThen

| 함수형 인터페이스 | 메소드 | 설명 | | — | — | — | | Consumer | T→ void accept(T t) | Supplier와 반대로 매개변수만 있고, 반환값이 없음 |

  • 예제) 람다식 표현
public class Main{
		public static void main(String[] args){

			Consumer<Integer> printT = (i) -> System.out.println(i);
			printT.accept(10); // 출력 : 10

		}
}
  • 예제) 메소드레퍼런스 표현
public class Main{
 public static void main(String[] args){

  Consumer<Integer> printT = System.out::println; // 메소드 레퍼런스로 표현
  printT.accept(10); // 출력 : 10

 }
}

Supplier

  • T 타입의 값을 제공하는 함수 인터페이스
    • T get()

| 함수형 인터페이스 | 메소드 | 설명 | | — | — | — | | Supplier | T get( ) T→ | 매개변수는 없고, 반환값만 있음. |

  • 예제
public class Main{
		public static void main(String[] args){

			Supplier<Integer> get10 = () -> 10; // 인자가 없음 .  return만..
			System.out.println(get10.get()); // 10
		}
}

Predicate

  • T타입을 받아서 boolean을 리턴하는 함수 인터페이스
    • boolean test(T t)
  • 함수 조합용 메소드
    • And
    • Or
    • Negate
함수형 인터페이스메소드설명
PredicateT ——> boolean test(T t) boolean ——>조건식을 표현하는데 사용됨. 매개변수는 하나, 반환 타입은 boolean
  • 예제) Predicate
public class Main{
	public static void main(String[] args){

		//1. String 타입 받을 때
		// 처음 "Dante"라는 단어가 들어가는 데이터가 있는지 확인
		Predicate<String> startsWithDante = (s) - > s.startsWith("Dante");

		//2. Integer 타입 받을 때
		// 짝수가 맞는지 확인
		Predicate<Integer> isEven = (i) -> i%2 == 0;

	}
}

UnaryOperator

  • Function<T, R>의 특수한 형태로, 입력값 하나를 받아서 동일한 타입을 리턴하는 함수 인터페이스
함수형 인터페이스메소드설명
UnaryOperatorT ——> T apply(T t) T ——>Function의 자손, Function과 달리 매개 변수와 결과의 타입이 같다.
public class Main{
		public static void main(String[] args){

			//Function<Integer, Integer> plus10 = (number) -> i + 10;

			UnaryOperator<Integer> plus10 = (number) -> i + 10;

		}
}

Funtion<T, R> 받는 타입과 반환 타입이 다르면 function을 쓰는게 맞다.

하지만 받는 타입과 반환타입이 같으면 UnaryOperator를 쓰는 것이 더 깔끔하다.

BinaryOperator

  • BiFunction<T, U, R>의 특수한 형태로, 동일한 타입의 입력값 두 개를 받아 리턴하는 함수 인터페이스
함수형 인터페이스메소드설명
BinaryOperatorT, T → T apply(T t, T t) → TBiFunction의 자손, BiFunction과 달리 매개변수와 결과의 타입이 같다.
  • 예제) BinaryOperator
public class Main{
		public static void main(String[] args){

			BinaryOperator<Integer> doublePlus = (n1, n2) -> n1 + n2;
			Integer sum = doublePlus.apply(1,1);
			System.out.println(sum); // return : 2
		}
}

매개변수가 두 개인 함수형 인터페이스

매개변수가 2개인 함수형 인터페이스는 접두사 ‘Bi’가 붙는다.

함수형 인터페이스메서드설명
BiConsumer<T, U>T, U → void accept(T t, U u)두 개의 매개변수만 있고, 반환값이 없음
BiPredicate<T, U>T, U → boolean test(T t, U u) boolean →조건식을 표현하는데 사용됨.
매개변수는 둘, 반환값은 boolean  
BiFunction<T, U, R>T, U → R apply(T t, U u) R →두 개의 매개변수를 받아서 하나의 결과를 반환

Tip. Supplier는 매개변수는 없고 반환값만 존재하는데, 메서드는 두 개의 값을 반환할 수 없으므로 BiSupplier가 없는 것이다.

UnaryOperator와 BinaryOperator

Function의 또 다른 변형으로 UnaryOperator와 BinaryOperator가 있다.

매개변수의 타입과 반환타입의 타입이 모두 일치한다는 점만 제외하고는 Function과 같다.

함수형 인터페이스메서드설명
UnaryOperatorT → T apply(T t) T→Function의 자손, Function과 달리 매개변수와 결과의 타입이 같다.
BinaryOperatorT, T → T apply(T t, T t) T →BiFunction의 자손, BiFunction과 달리 매개변수와 결과의 타입이 같다.

Tip.

UnaryOperator와 BinaryOperator의 조상은 각각 Function과 BiFunction이다.

참고 : 백기선 - The Java8