[사이드 프로젝트] 함수형 프로그래밍 익히기 With Java - Function Interface & Lambda

gimseonjin616·2022년 5월 11일
0

Function Interface

함수형 프로그래밍에서는 함수를 객체처럼 다룹니다. 그러나 자바에서는 객체를 무조건 클래스 단위로 구현해야해서 이 함수도 결국 클래스와 유사하게 구현해야합니다.

따라서 자바의 함수 구현은 class로 구현해야하며 Function<T, R>를 상속받아야 합니다.

예시 - 파라미터 1개

우선 파라미터를 받아서 10 더한 값을 반환하는 Add10이라는 함수를 만들어본다.

Function<>을 상속받아 Class Add10을 구현한 후, Abstract method인 apply를 구현한다.

import java.util.function.Function;

public class Add10 implements Function<Integer, Integer> {
    @Override
    public Integer apply(Integer integer) {
        return integer + 10;
    }
}

그 후, Main문에서 다음과 같이 선언한 후, apply 메소드를 통해 함수를 실행할 수 있다.

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

        Function<Integer, Integer> add10 = new Add10();

        int result = add10.apply(5);

        System.out.println(result);
    }
}

예시 - 파라미터 2개

위 경우는 파라미터가 1개인 경우다. 그렇다면 파라미터가 2개인 경우에는 어떻게 해야하는가?

그럴 때 사용하는 것이 BiFunction<T, U, R>이다.

사용법은 위 Function과 같으며 아래와 같이 구현할 수 있다.

public class BiAdd implements BiFunction<Integer, Integer, Integer> {
    @Override
    public Integer apply(Integer integer, Integer integer2) {
        return integer + integer2;
    }
}
public class Main {
    public static void main(String[] args){

        BiFunction<Integer, Integer, Integer> add = new BiAdd();

        int result = add.apply(5, 10);

        System.out.println(result);
    }
}

예시 - 파라미터 3개

자바에서 지원하는 Function으로는 파라미터 최대 2개까지 밖에 사용할 수 없다.

따라서 3개 이상을 사용하기 위해선 커스텀 Function Interface를 구현해야하는데 이때 사용할 수 있는 것이 바로 @FunctionalInterface다.

이 어노테이션을 통해 커스텀 Function Interface를 구현할 수 있으며 이를 상속받아 함수로 구현할 수 있다.

그 후에는 기존 Function과 BiFunction과 사용법은 같다.

@FunctionalInterface
public interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}
public class TriAdd implements TriFunction<Integer, Integer, Integer, Integer>{
    @Override
    public Integer apply(Integer integer, Integer integer2, Integer integer3) {
        return integer + integer2 + integer3;
    }
}

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

        TriFunction<Integer, Integer, Integer, Integer> triAdd = new TriAdd();

        int result = triAdd.apply(1,2,3);

        System.out.println(result);
    }
}

Lambda 표현식

위 방식으로 프로그래밍을 하면 새로운 함수가 필요할 때 마다 객체를 만들어줘야한다. 그러면 너무 많은 구현체가 생겨 유지보수나 디버깅이 어렵다.

이러한 문제를 해결하기 위해 Lambda 표현식을 사용할 수 있다. 람다는 익명함수를 뜻하며 런타임시 생성되어 바로 변수에 할당할 수 있도록 해준다.

사용방법은 아래와 같으며 상황에 따라 표현이 간결해질 수 있다.

// 기본 형태
(Object x) ->{
	return x + 10
}

// 1. 타입이 추론 가능할 경우 x 타입 생략 가능
(x) -> {
	return x + 10
}

// 2. 파라미터가 1개인 경우 () 생략 가능
x -> {
	return x+10
}

// 3. 바로 return할 시, { return } 생략 가능
x -> x + 10

이 Lambda를 사용할 시, Add10, Add, TriAdd 객체 구현체가 필요없어지며 Main 코드는 아래와 같이 수정할 수 있다.

public class Main {
    public static void main(String[] args){
        // 파라미터 1개
        Function<Integer, Integer> add10 = x -> x + 10;

        int result1 = add10.apply(5);

        System.out.println(result1);

        // 파라미터 2개
        BiFunction<Integer, Integer, Integer> add = (x, y) -> x+y;

        int result2 = add.apply(5, 10);

        System.out.println(result2);

        // 파라미터 3개
        TriFunction<Integer, Integer, Integer, Integer> triAdd = (x, y, z) -> x+y+z;

        int result3 = triAdd.apply(1,2,3);

        System.out.println(result3);
    }
}
profile
to be data engineer

0개의 댓글