본문 바로가기

Java

자바에서 제공하는 함수형 인터페이스 [더 자바, Java 8]

- 자바에서 미리 정의해 놓은 함수형 인터페이스들이 있습니다. 

  이 함수형 인터페이스들은 모두 java.lang.function 패키지에 들어 있습니다.

 

1) interface Function<T,R>

- Function 인터페이스를 보면 하나의 메소드가 정의되어 있습니다. 

  T라는 타입을 받아서, R이라는 타입을 리턴합니다. 

  대표적인 수학적인 함수와도 일치합니다. 

  두 개의 타입이 다를 수 있기 때문에, T와 R로 정의되어 있습니다. 

package me.whiteship.java8to11;

public class Plus10 implements Function<Integer, Integer> {
	@Override
    public Integer apply(Integer integer){
        return integer+10;
    }
}
package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Plus10 plus10 = new Plus10();
       System.out.println(plus10.apply(1));
   } 
}

 

- 혹은 다음과 같이 함수형 인터페이스를 바로 사용할 수도 있습니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Function<Integer, Integer> plus10 = (i) -> i + 10;
       
       System.out.println(plus10.apply(1)); 
   } 
}

- 또한, 함수를 조합할 수 있는 메소드를 디폴트 메소드로 제공합니다. 

  그것에는 andThen과 compose가 있습니다. 

- 함수 조합은 다음과 같이 할 수 있습니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Function<Integer, Integer> plus10 = (i) -> i + 10;
       Function<Integer, Integer> multiply2 = (i) -> i * 2;
       
       System.out.println(multiply2.apply(1)); 
   } 
}

 

- plus10, multiply2 함수를 compose로 조합할 수도 있습니다. 

  이는 multiply2를 먼저 적용하고, 그 다음에 plus10을 적용하겠다는 의미입니다. 

  즉, 어떤 값이 들어오면 x2를 먼저하고, 그 값에 +10을 해줍니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Function<Integer, Integer> plus10 = (i) -> i + 10;
       Function<Integer, Integer> multiply2 = (i) -> i * 2;
       
       Function<Integer, Integer> multiply2AndPlus10 = plus10.compose(multiply2);
       System.out.println(multiply2AndPlus10.apply(2));
   } 
}

// 결과 값
14

- 반면, andThen을 하면 뒤에 붙이는 것입니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Function<Integer, Integer> plus10 = (i) -> i + 10;
       Function<Integer, Integer> multiply2 = (i) -> i * 2;
         
       System.out.println(plus10.andThen(multiply2).apply(2));
   } 
}

// 결과 값
24

 

- BiFunction은 Function과 비슷한데, 값을 2개 받습니다. 

  입력 값을 T, U 2개 받아서, 하나를 내보냅니다. 

  그리고 또 다른 R이라는 타입으로 리턴을 합니다. 

 

- Consumer는 받아서 아무것도 리턴을 하지 않습니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Consumer<Integer> printT = (i) -> System.out.println(i);
       printT.accept(10);
   } 
}

// 결과 값
10

 

- Supplier는 어떤 값을 하나 가져오는 함수형 인터페이스입니다. 

  무언가를 받지 않고, 내가 받아올 값을 정의합니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Supplier<Integer> get10 = () -> 10;
       System.out.println(get10.get());
   }  
}

// 결과 값
10

- Predicate 같은 경우는 어떤 인자 값을 하나 받아서, 

  true, false를 리턴해주는 함수형 인터페이스입니다. 

  boolean으로 결과값이 나오기 때문에 negate, and, or 등과 조합이 가능합니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       Predicate<String> startsWithKeesum = (s) -> s.startsWith("Keesun");
       Predicate<Integer> isEven = (i) -> i%2 == 0;
   }  
}

// 결과 값

- UnaryOperator는 Function 함수형 인터페이스의 특수한 케이스입니다. 

  입력하는 값이 하나이고,

  입력하는 타입의 값과 리턴하는 타입의 값이 같으면 UnaryOperator를 사용할 수 있습니다. 

  UnaryOperator는 Function을 상속 받았기 때문에,

  Function에서 제공하는 default 메소드들을 사용할 수 있습니다. 

package me.whiteship.java8to11;

public class Foo{

   public static void main(String[] args){
       UnaryOperator<Integer> plus10 = (i) -> i + 10;
       UnaryOperator<Integer> multiply2 = (i) -> i * 2;
         
       System.out.println(plus10.andThen(multiply2).apply(2));
   } 
}

// 결과 값
24

 - BinaryOperator는 BiFunction의 특수한 형태입니다. 

   BinaryOperator는 BiFunction의 3가지 값의 타입이 모두 같은 경우 사용 가능합니다. 

 

 

참고

- 백기선, 더 자바, Java 8