본문 바로가기
개발 지식/Java

[Java] 함수형 인터페이스 @FunctionalInterface - 3. Function

by 에르주 2022. 4. 13.
반응형

2022.03.26 - [개발 지식/Java] - [Java] 함수형 인터페이스 @FunctionalInterface - 2. Consumer

 

[Java] 함수형 인터페이스 @FunctionalInterface - 2. Consumer

2022.03.11 - [개발 지식/Java] - [Java] 함수형 인터페이스 @FunctionalInterface - 1. Predicate [Java] 함수형 인터페이스 @FunctionalInterface - 1. Predicate 개발을 진행하다보면 람다 표현식을 많이 쓰게..

erjuer.tistory.com

 

이번에는 마지막 3번째 Function 인터페이스를 정리하고자 한다.

Function 인터페이스는 제네릭 형식 T를 매개변수로 받아 제네릭 형태의 R을 리턴하는 추상 메서드 apply를 정의한다.

(제네릭 T, R에 대해 이해하기 보다는 단순히 Return 타입이 void가 아닌 메소드라고 이해하는게 더 쉬울 것 같다. 단, 파라미터 값이 있는 메소드이다.)

@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t); // 무슨 메소드를 구현할 지는 모르겠지만 제네릭 R을 리턴하는 메소드
    
}


public String goodTaste(Integer kcal, String message) {
	
    if(kcal > 500) message = "매우 맛있는 음식";
    if(kcal < 500 && kcal > 200) message = "적당히 맛있는 음식";
    else message = "맛있을 뿐만 아니라 많이 먹을 수 있는 음식";
    
    return message;

}

 

예를 들면 goodTaste라는 메소드는 파라미터 값으로 kcal값과 message를 받아 kcal 값에 따라 message를 반환한다.

Function 또한 제네릭 형태의 T ( ≒ kcal) , R (  ≒ message) 을 받아 T (  ≒ kcal) 를 활용하여 R (  ≒ message) 값을 반환하므로 두개의 객체는 유사하다고 볼 수 있다.

 


 

이제 코드로 예를 들어 Function 함수형 인터페이스를 다뤄보자.

 

  // T,R : 제네릭 T를 받아서 R을 리턴한다.
  public <T,String> Function<T,String> paymentInterFaceByMeat() {

    return new Function<T, String>() {
      @Override
      public String apply(T t) {

        Meat meat = (Meat) t;

        if(Objects.equals(meat.getKindValue(), "한우")) return (String) "임원 법인카드";
        if(Objects.equals(meat.getKindValue(), "양")) return (String) "팀장 법인카드";
        if(Objects.equals(meat.getKindValue(), "돼지")) return (String) "부가급 나온달 개인카드";
        if(Objects.equals(meat.getKindValue(), "닭")) return (String) "부모님 카드";
        return (String) "개인카드";
      }
    };
  }
  
  
  // paymentInterFaceByMeat와 paymentMethodByMeat는 같은 로직을 탄다.
  
  public String paymentMethodByMeat(Meat meat) {
  	
    if(meat.getKindValue().equals("한우") return "임원 법인카드";
    if(meat.getKindValue().equals("양") return "팀장 법인카드";
    if(meat.getKindValue().equals("돼지") return "부가급 나온달 개인카드";
    if(meat.getKindValue().equals("닭") return "부모님 카드";
    
    return "개인카드"
    
  
  }

paymentInterFaceByMeat 메소드는 Meat 객체를 받아 meat의 종류에 따라 결제 카드 방법을 리턴한다.

(Function 인터페이스 안의 Apply 메소드를 Meat 객체의 종류에 따라 결제 카드 방법을 Override 했다.)

 

즉, 이 코드 paymentInterFaceByMeat에 사용되는 제네릭 T , R은 각각 Meat, String이라고 볼 수 있으며  payMethodMethodByMeat와 동일한 로직을 처리한다.

 

// meatList, Function 인터페이스
public <T> void FunctionMethod(List<Meat> meatList, Function<T, Object> functionIf) {

    for (Meat meat: meatList) {
      String cardValue = (String) functionIf.apply((T) meat);
      stem.out.println(meat.getKindValue() + "을/를 먹을 때에는 " + cardValue +"로 결제해야 한다.");
}


public static void main(String[] arg) {
 	List<Meat> meatList = Arrays.asList(new Meat(400,"한우"), 
                                        new Meat(500,"돼지"), 
                                        new Meat(300,"닭"), 
                                        new Meat(150,"닭가슴살"));
    FunctionEx functionEx = new FunctionEx();
    functionEx.FunctionMethod(meatList, functionEx.paymentInterFaceByMeat());    
}

 

이제 meat객체의 List를 받아 종류에 따라 console창에 message를 뿌려주려고 한다. 2번째 파라미터인 functionIf 는 위에서 정의한 paymentInterFaceByMeat를 쓰려고 한다.

콘솔 결과

그 결과 kindValue (한우, 돼지, 닭, 닭가슴살)에 따라 결제 카드 방법을 정의한 것이 콘솔에 나타 난 것을 확인 할 수 있다.

 

 

 

 

또한 Function 함수형 인터페이스는 Stream API의 map 메소드에서도 사용한다.

map 메소드에 Funciton 함수형 인터페이스가 쓰인다.

 // stream의 map 메소드
 <R> Stream<R> map(Function<? super T, ? extends R> mapper);
 
public static void main(String[] arg){

    List<Meat> meatList = Arrays.asList(new Meat(400,"한우"), new Meat(500,"돼지"), new Meat(300,"닭"), new Meat(150,"닭가슴살"));
    FunctionEx functionEx = new FunctionEx();
    meatList.stream().map(functionEx.paymentInterFaceByMeat()).forEach(System.out::println);
}

/*
임원 법인카드
부가급 나온달 개인카드
부모님 카드
개인카드
*/

 

 

 

지금 까지 함수형 인터페이스 

 

1. Predicate

2. Consumer

3. Function

 

세가지 경우에 대해 간단히 정리하였고 Stream API의 어떤 메소드에 활용할 수 있는지 알아봤다.

실무 개발을 진행하다보면 Stream API를 많이 사용하고 있는데 내 자신에게도 이 글을 보는 분에게도 도움이 되었으면 한다.

 

끝.

 

자세한 코드는 다음 git을 참고

 

https://github.com/pminsu01/JavaStudy

 

GitHub - pminsu01/JavaStudy: 자바 자체 스터디

자바 자체 스터디. Contribute to pminsu01/JavaStudy development by creating an account on GitHub.

github.com

 

 

 

 

 

 

반응형

댓글