java/메모장

람다식의 스트림 함수

choi-dev 2024. 2. 12. 01:19

일반적으로 람다식은 익명 함수라고도 불린다. 일반적으로 함수는 이름이 존재하는데 람다식에는 존재하지 않는다. 코드로써 일반 함수와 람다식을 비교하면 다음과 같다.

 

// 일반함수식
public int sum(int x, int y) {
    return x + y;
}

// 람다식
(x, y) -> x + y

일반 함수식에는 sum이라는 메소드명이 있지만 람다식에는 함수명이 존재하지 않는다. 자바에서는 스트림이 람다식으로 표현한다. 람다식에는 여러 스트림 함수가 존재하는데 통상 자주 사용되는 3가지 정도만 정리해보려고 한다.

 

Filter

특정 조건을 만족하는 데이터만 걸러내는데 사용된다.

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers_array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};

        // 50 이상의 배열만 출력한다.
        System.out.println(Arrays.toString(Arrays.stream(numbers_array)
                .filter(i -> i >= 50)
                .toArray()));
    }
}

 

Map

데이터를 변형하는데 사용된다.

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers_array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};

        // 배열에 각각 *2를 진행한다.
        System.out.println(Arrays.toString(Arrays.stream(numbers_array)
                .map(i -> i * 2)
                .toArray()));
    }
}

 

Reduce

스트림의 요소들을 하나의 데이터로 만드는데 사용된다. 여기서 하나 확인해야할 것은 reduce의 경우에 Optional 인자로 리턴한다.

import java.util.Arrays;
import java.util.OptionalInt;

public class Main {
    public static void main(String[] args) {
        int[] numbers_array = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
        OptionalInt sum = Arrays.stream(numbers_array)
                .reduce((x, y) -> x + y);

        sum.ifPresent(s -> System.out.println(s));
    }
}

 

예시

프로그래머스 코딩테스트 문제를 풀다가 람다식으로 해결한 분의 코드가 있어서 천천히 알아보겠다.

 

https://school.programmers.co.kr/learn/courses/30/lessons/181884

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제의 핵심은 배열 안의 값을 계속 더해주면서 n이라는 파라미터보다 커졌을 때 리턴해주는 것을 의미한다.

 

import java.util.*;

class Solution {
    public int solution(int[] numbers, int n) {
        int answer = 0;
        
        for (int i = 0; i < numbers.length; i++) {
            answer += numbers[i];
            if (answer > n) {
                break;
            }
        }
        return answer;
    }
}

람다식을 사용하지 않는다면 반복문을 통해 값을 하나씩 추출하고 하나의 변수에 이를 계속 더 해준 다음 조건문을 통해 n보다 커졌을 시에는 반복문에서 탈출하도록 설계했다. 여기서 람다식을 사용하면 어떤 스트림 함수를 써야할까? 하나의 데이터를 만드는데 용이한 reduce 함수가 제일 적절해보인다. 이를 사용해서 만들어보겠다.

 

import java.util.*;

class Solution {
    public int solution(int[] numbers, int n) {
        return Arrays.stream(numbers).reduce(0, (answer, number) -> n >= answer ? answer + number : answer);
    }
}

생각보다 단순하다. answer, number를 매개변수로 받고 n이 answer보다 크면 계속 더해주고 아니면 answer로 리턴해준다. 

 

람다식이 무조건 좋을까?

람다식을 통해서 무분별한 루프문을 사용하지 않게 될 수도 있고 코드가 간결해져서 가독성이 향상되는 등 많이 이점이 분명 존재한다. 하지만 코드는 나 혼자서만 사용하는 것도 아니고 현업의 기준으로 봤을 때는 애매할 수 있다고 생각한다.

 

람다식을 대중화되면서 많은 사람들이 알고는 있다고 생각하지만 아직도 모르는 사람 또한 있을 것이다. 지나치게 많은 람다식을 사용하게 되면 오히려 장점이었던 가독성이 더 어려워지는 불상사가 발생할 수도 있고 자주 사용되는 함수일 경우에 재사용할 수가 없어 다시 저 람다식을 그대로 가져와서 사용해야 하는 경우도 발생할 것이다.

 

상황에 맞게 람다식을 조정해서 사용하고 디버깅이 많이 필요한 로직이라면 람다식보다는 반복문을 통해 추적하는 것이 되려 나을 때도 있으니 무분별하게 사용하지는 말자.

 

람다식 연습

https://school.programmers.co.kr/learn/courses/30/lessons/181835

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해당 문제를 람다식으로 풀어보면 도움이 될 듯하다.