개발/JAVA

JAVA의 함수형 프로그래밍과 Stream 활용하기

예니03 2025. 1. 16. 10:46
반응형

안녕하세요! 오늘은 자바에서 함수형 프로그래밍과 스트림을 활용하는 방법에 대해 이야기해 보겠습니다. 이 글은 자바를 처음 배우는 분들도 쉽게 이해할 수 있도록 차근차근 설명하겠습니다. 함께 시작해볼까요?

1. 함수형 프로그래밍이란?

함수형 프로그래밍은 데이터를 변경하지 않고 작업 수행 규칙(함수)을 중심으로 프로그램을 작성하는 방식입니다. 주요 특징은 다음과 같습니다:

  • 불변성: 데이터를 변경하지 않고 새로운 데이터를 생성합니다.
  • 일급 객체로서의 함수: 함수는 변수처럼 전달, 반환이 가능합니다.
  • 부수 효과 최소화: 상태 변경이나 외부에 영향을 주는 작업을 줄입니다.

자바에서는 람다식과 스트림 API를 활용해 함수형 프로그래밍 스타일로 코드를 작성할 수 있습니다.

2. 람다식

람다식은 이름 없는 일회성 함수입니다. 코드를 간결하고 읽기 쉽게 작성할 수 있죠. 예제를 보며 이해해 봅시다.

예제: MyFunction 인터페이스와 람다식

@FunctionalInterface
public interface MyFunction {
    int getResult(int x, int y);
}

위 인터페이스를 사용하는 다양한 방식입니다:

MyFunction add = (x, y) -> x + y;  // 두 수의 합
MyFunction max = (x, y) -> x > y ? x : y;  // 두 수 중 큰 값

실행 코드

public static void main(String[] args) {
    MyFunction add = (x, y) -> x + y;
    System.out.println(add.getResult(10, 20)); // 출력: 30

    MyFunction max = (x, y) -> x > y ? x : y;
    System.out.println(max.getResult(10, 20)); // 출력: 20
}

이제 익명 클래스 없이도 간결한 코드를 작성할 수 있습니다.

3. 스트림 API

스트림은 데이터를 물결의 흐름처럼 처리할 수 있는 기능입니다. 여러 단계를 거쳐 데이터를 필터링하거나 변환할 수 있습니다. 크게 두 가지로 나뉩니다:

  1. 중간 연산: 필터링, 매핑, 정렬 등 데이터 변환 작업 수행
  2. 최종 연산: 데이터를 순회하거나 집계

스트림의 생성

  • 배열 스트림:
int[] scores = {80, 90, 70, 100, 60, 50};
IntStream arrStream = Arrays.stream(scores);
  • 컬렉션 스트림:
List<Student> students = new ArrayList<>();
students.add(new Student("홍길동", 90, 95, 100));
Stream<Student> objStream = students.stream();

forEach로 순회

Arrays.stream(scores).forEach(n -> System.out.print(n + " "));

필터와 정렬

  • 70점 이상인 점수 필터링:
Arrays.stream(scores).filter(n -> n >= 70).forEach(System.out::println);
  • 학생 평균 점수로 정렬:
students.stream()
    .filter(s -> s.getAverage() >= 70)
    .sorted((s1, s2) -> s1.getName().compareTo(s2.getName()))
    .forEach(System.out::println);

map으로 데이터 변환

int[] doubled = Arrays.stream(scores).map(n -> n * 2).toArray();
System.out.println(Arrays.toString(doubled));

reduce로 합계 구하기

int total = Arrays.stream(scores).reduce(0, (acc, curr) -> acc + curr);
System.out.println("Total: " + total);

4. 실습: 학생 클래스와 스트림

아래는 학생 데이터를 처리하는 예제입니다:

class Student {
    private String name;
    private int kor, eng, math;

    public Student(String name, int kor, int eng, int math) {
        this.name = name;
        this.kor = kor;
        this.eng = eng;
        this.math = math;
    }

    public String getName() { return name; }
    public int getTotal() { return kor + eng + math; }
    public double getAverage() { return getTotal() / 3.0; }
}

학생 리스트 처리

List<Student> students = Arrays.asList(
    new Student("홍길동", 90, 95, 100),
    new Student("고길동", 80, 50, 90)
);

students.stream()
    .filter(s -> s.getAverage() >= 70)
    .forEach(System.out::println);

5. 마무리

이번 글에서는 자바의 람다식과 스트림을 활용해 데이터를 처리하는 방법을 알아보았습니다. 함수형 프로그래밍 스타일은 코드를 간결하게 만들고, 데이터를 효과적으로 처리할 수 있도록 도와줍니다.

반응형