본문 바로가기
Today I learned

2021 11 18 실무에 어떻게 적용하면 좋을지 궁금한 functional interface

by soheemon 2021. 11. 18.

함수형 인터페이스는 하나의 추상메서드를 가지고있는 인터페이스를 의미한다.

java.util.function 하위에 있다.

https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

public interface FunctionalInterface {
	public abstract void someThing(String name);
}

FunctionalInterface func = name -> System.out.println(name);

func.someThing("soheemon");

 

아래와 동작이 같다. 다른점이 있다면 함수형 인터페이스는 함수를 1급객체로서 return 하거나 파라미터로 전달할 수 있다는점.

c의 포인터와 비슷...

 

FunctionalInterface func = new FunctionalInterface() {
 @Override
  public void something(String name) {
  	System.out.println(name);
  }
}

func.doSomething("soheemon!");

 

1) Function, The Transformer..!


@FunctionalInterface
public interface Function<t, r>

<T> – 함수 입력값을 의미한다.
<R> – 함수 반환값을 의미한다.

identity는 입력받은값을 그대로 반환한다.
static <T> Function<T, T> identity() {
	return t -> t;
}

// function 인터페이스의 추상메서드. T를 입력받아서 R을 반환한다.
R apply(T t);

function 예제.

        // 람다 사용하기 전!
        Function<String, Integer> toInt = new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        };

        toInt.apply("100"); //사용...

        //람다 적용
        Function<String, Integer> toInt2 = (str) -> {
            return Integer.parseInt(str);
        };
        toInt2.apply("100");

2) Consumer

@FunctionalInterface
public interface Consumer<T>

// 소비한다.
Consumer<String> consumer = (str) -> System.out.println(str);

3) Predicate

대충 이렇게 쓰는구나아.. 필터 안에 로직이 길어지면 확실히 functional interface로 로직을 빼는게 좋아보이네..

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);
    
        List test = new ArrayList();
        test.add(1);
        test.add(2);
        test.add(3);
        test.add(4);
        test.add(5);
        test.add(6);

        Predicate<Integer> test1 = (num) -> (Integer)num > 2;
        
        //왠지.. Predocate 안에 추상메서드가 하나밖에 없어서 가능한듯...
        test.stream().filter(test1).forEach(num -> System.out.println(num));
        
        
        // 만약 조건이 변경되면 ! predicate를 여러개 만들어야함...! ㅠ
        
        Predicate<Integer> isPositive = i -> i > 2;

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        for(Integer num : numbers){
            if(isPositive.test(num)){
                System.out.println(num);
            }
        }
        
        /**** best case *****/
                List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        Predicate<Integer> isPositive = i -> i > 2;
        filter(numbers, (number) -> number == 2);
        filter(numbers, isPositive);

    }
    public static <T> List<T> filter (List<T> list, Predicate<T> filter){
        List<T> result = new ArrayList<>();
        for(T input : list){
            if(filter.test(input)){
                result.add(input);
            }
        }
        return result;
    }

4) supplier.  조건에 따라서 함수호출을 미룰수 있따...! 이건 js에서도 활용 가능할것같다.

@FunctionalInterface
public interface Supplier<T> {
    T get();
    
    public static void main(String[] args) {

        printIfValidIndex(10, () -> getVeryExpensiveValue());   //아직 실행은 안함.. 이거 왠지 js에서도 활용 가능할것같애...!
    }
    //오래걸리는 작업을 가정...
    private static String getVeryExpensiveValue(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "soheemon....!";
    }

    private static void printIfValidIndex(int number, Supplier<String> valueSupplier) {
        if(number >= 0){
            System.out.println(valueSupplier.get());
        }else{
            System.out.println("invalid");
        }
    }
}

댓글