스터디 포스트 >  자바 조금 더 알기

자바의 함수형 프로그래밍

박두원 멘토
백엔드 개발자이고, 기술 공부를 좋아합니다.

자바 조금 더 알기 - 2주차

 
💡
자바의 함수형 프로그래밍에 대해 이해하고, 사용하는 법을 익힌다.
 

함수형 프로그래밍

함수형 프로그래밍 : 함수에 일급 시민을 적용시키는 것

일급 시민 (First Class Citizen) 특징

  1. 변수에 할당할 수 있다.
  1. 인자로 전달할 수 있다.
  1. 반환 값으로 전달할 수 있다.
 

stream

데이터의 흐름
List<Integer> numbers = List.of(1,3,4,6,8,11);

중간 연산

  • sort : 전달한 Comparator에 따라 데이터를 정렬한다.
numbers.stream()
    .sorted((n1, n2) -> Integer.compare(n1, n2))
  • distinct : 중복 데이터를 걸러낸다
numbers.stream()
    .distinct()  // 데이터 중에 중복되는 값이 있으면 걸러낸다.
  • filter : stream 구성 데이터 중 조건에 따라 일부를 걸러낸다.
numbers.stream()
   .filter(number -> number % 2 == 0) // 짝수만 통과한다.
  • map : 스트림 데이터를 원하는 형태로 변환한다.
numbers.stream()
    .map(n -> n * n) // 데이터를 제곱수로 변환
 

최종 연산

  • reduce : 스트림 요소를 줄여나가면서 연산을 수행하고 최종 결과를 반환한다.
numbers.stream()
    .reduce(0, (n1, n2) -> n1 + n2);  // 초기값 0, 수행할 연산을 전달한다.
  • max : 최대값을 구한다.
numbers.stream()
    .max((n1, n2) -> Integer.compare(n1, n2))
  • min : 최소값을 구한다.
numbers.stream()
    .min((n1, n2) -> Integer.compare(n1, n2))
  • collect : 구현된 방법에 따라 스트림 요소를 수집한다.
numbers.stream()
     .sorted((n1, n2) -> Integer.compare(n1, n2))
     .collect(Collectors.toList());
 

함수형 프로그래밍 vs 구조적 프로그래밍

  • 루프 문 - mutation 가변
public Integer listSum(List<Integer> numbers) {
  int sum = 0;
  for (Integer num : numbers) {
    sum += num;  // sum에 대해 값의 변경이 존재한다.
  }
  return sum;
}
 
  • stream
public Integer listSum(List<Intger> numbers) {
  return numbers.stream()
          .reduce(0, (num1, num2) -> num1 + num2);  // 지역변수에 대해 신경쓰지 않고, 그저 더하는 '로직'에만 집중
}
  1. 함수형 프로그래밍에서는 변수 변이를 피한다. → 굳이 값이 변하는 변수를 넣지 않는다.
  1. 무엇을 할지에 집중한다. → 어떻게 하는지가 아닌 무엇을 할지에 집중한다. 결과가 나오는 과정(로직)에 대해선 관심을 갖지 않는다.
 

람다 함수

익명함수를 지칭하는 용어.
  • 함수 생성의 단축형
  • 여러 줄의 코드를 가질 수 있다.
// 매개변수가 여러개인 경우
(매개변수1, 매개변수2) -> {
  //로직
  return ..;
}

----------------------------------------------------------------
// 매개변수가 1개 & return 값만 있는 경우
매개변수 -> ""
 

함수형 인터페이스

  • Predicate : 인자 하나를 받아서 boolean 타입을 리턴한다.
@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}
  • Consumer : 인자 하나를 받고 아무것도 리턴하지 않는다.
@FunctionalInterface
public interface Consumer<T> {
  void accept(T t);
}
  • Function : T 타입 인자를 받아서 R 타입을 리턴한다.
@FunctionalInterface
public interface Function<T, R> {
  R apply(T t);
}
 

메서드 참조

람다 표현식에서 불필요한 매개변수를 제거하고 사용할 수 있도록 해주는 기능
numbers.stream()
        .sorted((n1, n2) -> Integer.compare(n1, n2))

----------------------------------------------------------------
numbers.stream()
        .sorted(Integer::compare)
  • 정적 메서드 뿐만 아니라 인스턴스 메서드도 메서드 참조로 작성이 가능하다.
 
 
[ 추가 공부 자료 ]
 
 
[ 참고 자료 ]
 
 
 
본 스터디는 Udemy의 <【한글자막】 완전 초보자를 위한 Java 프로그래밍 : 단기간에 Java 완벽 정복> 강의를 활용해 진행됐습니다. 강의에 대한 자세한 정보는 아래에서 확인하실 수 있습니다.
 
 
프밍 스터디는 Udemy Korea와 함께 합니다.
 
원하는 스터디가 없다면? 다른 스터디 개설 신청하기
누군가 아직 원하는 스터디를 개설하지 않았나요? 여러분이 직접 개설 신청 해 주세요!
이 포스트는
"자바 조금 더 알기" 스터디의 진행 결과입니다
진행중인 스터디
자바 조금 더 알기
자바의 기본적인 문법(변수, if, for 등)을 알고 계신 분들과 함께 자바에 대해 조금 더 공부해보는 스터디를 진행하려고 합니다. 평소 제네릭, 함수형 프로그래밍, 스레드와 동시성, synchronized 등에 대한 궁금증을 가지고 계셨던 분들 함께 공부해요!
박두원 멘토
백엔드 개발자이고, 기술 공부를 좋아합니다.