[JAVA] 함수형 인터페이스, 람다식, Stream API

정원석·2024년 4월 2일

함수형 인터페이스

함수형 인터페이스란 단 하나의 추상 메서드를 가진 인터페이스를 의미한다. 함수형 인터페이스는 @FunctionalInterface 어노테이션을 사용해 표시할 수 있다. 이 어노테이션은 선택 사항이지만, 추상메서드는 하나만 가지고 있어야 한다.

//부모 클래스
@FunctionalInterface //함수형 인터페이스
public interface MathOperation {
    public int operation(int x, int y); // 추상메서드
}

//자식 클래스(인터페이스 구현)
public class MathOperationImpl implements MathOperation{
    @Override
    public int operation(int x, int y) {
        return x+y;
    }
}

//메인클래스
public class FunctionInterfaceTest1 {
    public static void main(String[] args) {
        MathOperation mo = new MathOperationImpl();
        int result = mo.operation(10, 20);
        System.out.println(result);
    }
}

//구현클래스를 따로 만들지 않고 내부 익명클래스로 구현
public class FunctionInterfaceTest2 {
    public static void main(String[] args) {
        // MathOperation 인터페이스를 내부 익명내부클래스로 구현해보자.
        MathOperation mo = new MathOperation() {
            @Override
            public int operation(int x, int y) {
                return x+y;
            }
        };
        int result = mo.operation(10, 20);
        System.out.println(result);
    }
}

람다식 이란?

람다식은 함수형 프로그래밍에서 사용되는 함수를 간결하게 표현하기 위한 방법중 하나이다. 메서드에 대한 구현을 간결하게 표현하는 방법이다.

@FunctionalInterface //함수형 인터페이스
public interface MathOperation {
    public int operation(int x, int y); // 추상메서드
}

//람다 클래스
public class LambdaExample {
    public static void main(String[] args) {
        //MathOperation add = (int x, int y) -> {return x+y;};
        //코드를 간결하게 쓸 수 있고 확장, 구현 쉽다.
        MathOperation add = (x,y) ->  x+y;
        MathOperation multi = (x,y) ->  x*y;
        int result = add.operation(10, 20);
        System.out.println(result);
        int mulresult = multi.operation(10, 20);
        System.out.println(mulresult);
    }
}

두 개의 정수를 더하는 메서드를 람다식으로 구현하면 다음과 같다.
(int x, int y) -> { return x + y; }

람다 표현식을 메서드 내에서 사용하거나 매서드의 인자로 전달

//인터페이스
@FunctionalInterface
public interface StringOperation {
    public String apply(String s);
}

//메인클래스
public class LambdApply {
    public static void main(String[] args) {
        StringOperation toUpperCase = s -> s.toUpperCase();
        StringOperation toLowerCase = s -> s.toLowerCase();

        String input = "Lambda Expressions";
        System.out.println(processString(input, toUpperCase));
        System.out.println(processString(input, toLowerCase));
    }
    public static String processString(String input, StringOperation operation){
        return operation.apply(input);
    }
}

람다표현식을 processString 메서드의 인자로 전달하여 결과를 출력하고 있다. 이처럼 람다 표현식은 메서드 내에서 사용할 수 있으며, 메서드의 인자로 전달할 수도 있어 유연성을 높일 수 있다.

Stream API

배열의 원소들을 스트림 형태로 변환하여 처리할 수 있게 하는 것이다. 스트림은 원본 데이터를 변경하지 않고, 필요한 데이터 처리 작업을 적용한 결과를 생성하기 때문에 인덱스를 통한 접근을 제공하지 않는다.

public class StreamAPITest {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        /*int even = 0;
        for (int num : numbers) {
            if (num % 2 == 0) {
                even += 2;
            }
        }*/
        int sumOfEvens = Arrays.stream(numbers)
                .filter(n -> n % 2 == 0) //람다식
                .sum();
        System.out.println(sumOfEvens);

        int[] evenNumbers = Arrays.stream(numbers)
                .filter(n -> n % 2 == 0)
                .toArray();
        for (int even : evenNumbers) {
            System.out.println(even);
        }
    }
}

filter( )를 통해 메서드를 처리하고 sum과 toArray를 이용해 종료한다.

스트림 API와 함수형 인터페이스를 이용해 List에 저장된 정수들의 짝수여부를 판별하고, 짝수들만 필터링하여 정렬하고, 각 숫자를 제곱한 후 모든 숫자의 합을 계산해보자.

public class StreamExample {
    public static boolean isEven(int number){
        return number%2==0;
    }
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Predicate<Integer> isEven = n->n%2==0;
        int sumOfSquares = numbers.stream()
                .filter(StreamExample::isEven) //
                .sorted()
                .map(n->n*n)
                .reduce(0, Integer::sum);
        System.out.println(sumOfSquares);
    }
}
  • numbers 리스트를 스트림으로 변환한다.
  • filter 메서드를 사용해 짝수만 필터링한다. 여기서 pridicate 함수형 인터페이스를 사용한다.
  • sorted( )메서드를 사용해 정렬한다.
  • map( ) 메서드를 이용해 각 숫자를 제곱한다.
  • reduce( ) 메서드를 이용해 합계를 계산한다. 이 후 출력한다.
profile
Back-End-Dev

0개의 댓글