Java Study

Lamda(람다식)

Z00_HWAN_99 2024. 7. 12. 17:17
728x90
반응형

람다식이란?

  • Java 8 도입된 기능.
  • 함수형 프로그래밍 : 함수를 정의하고 이 함수를 데이터 처리부로 보내 데이터를 처리하는 기법.
  • 데이터 처리부는 제공된 함수의 입력값으로 데이터를 넣고 함수에 정의된 처리 내용을 실행.
  • 람다식
    • 데이터 처리부에 제공되는 함수 역할을 하는 매개변수를 가진 중괄호 블록.
    • 메서드에 인수를 전달하거나 변수에 저장하는 방법을 기술한 식.
  • 람다 표현식
    • 매개변수 리스트 : 매개변수 (,)로 구분하여 0개 이상의 매개변수 일 수 있음.
    • 람다 연산 기호 : 화살표 연산자( -> )
    • 람다 본문(람다 호출될 때 실행될 코드)에서 매개변수 리스트를 분리. 즉, 함수 시그니처와 본문 사이의 다리 역할.
  • 자바는 람다식을 익명 구현 객체로 변환.

함수형 인터페이스

  • 인터페이스가 단 하나의 추상 메서드(SAM - Single Abstract Method)를 가지는 것.
  • 인터페이스가 함수형 인터페이스임을 보장하기 위해서는 @FunctionalInterface 어노테이션을 붙임.
  • @FunctionalInterface : 컴파일 과정에서 추상 메서드가 하나인지 검사하여 정확한 함수형 인터페이스를 작성할 수 있게 도와주는 역할.
@FunctionalInterface
interface MathOperation(
    int operate(int a, int b);
)
  • 의미 : MathOperation을 사용하면 operate메서드를 구현하는 람다 표현식을 만들어 두 정수의 대해 다양한 수학적 연산을 수행 할 수 있음.

예제

package lamda;

import java.io.IOException;

public class LamdaEx02 {

  public static void main(String[] args) throws IOException {
    //문제 1. 두 정수를 받아서 그 합을 반환하는 람다식 작성하세요
    //1.두 정수를 받아 그 합을 반환하는 람다식 작성.
    MathOperation addition = (a, b) -> (a+b);

    //2. 한수형 인터페이스 인스턴스 생성 operate() 호출 결과 반환
    int result1 = addition.operate(5, 3);
    System.out.println("Result1 = " + result1);

    ////////////////////////////////////////////////////////
    //문제 2. 문자열을 받아 그 길이를 반환하는 람다표현식을 작성하세요.
    //1. 인터페이스의 이름 : StringOperation

    StringOperation length = string -> string.length();
    int result2 = length.getLength("Hello Lamda");
    System.out.println("Result2 = " + result2);

    //문제 3. 정수 배열을 받아 모든 짝수의 합을 반환하는 람다 표현식 작성.
    //인터페이스의 이름 : ArrayOperation
    ArrayOperation evenSum = numbers -> {
      int sum = 0;
      for (int num : numbers){
        if (num % 2 ==0) sum += num;
      }
      return sum;
    };
    int[] arr = {1,2,3,4,5};
    int result3 = evenSum.calculateSum(arr);
    System.out.println("Result3 = " + result3);
  }


  //1. 두 개의 정수를 받아 정수를 반환하는 단일메서드 'operate'가 있는 함수형 인터페이스 mathOperation을 정의
  //2. 두 개의 정수 a, b 를 더하는 람다표현식을 생성(a, b) -> a+b
  //3. 람다 표현식을 사용하여 함수형 인터페이스의 인스턴스를 생성하고 operate()호출해서 두 수샂의 합을 구한다.
  @FunctionalInterface
  interface MathOperation{
    int operate(int a, int b);
  }

  @FunctionalInterface
  interface StringOperation{
    int getLength(String string);
  }

  @FunctionalInterface
  interface ArrayOperation{
    int calculateSum(int[] numbers);
  }
}

 

람다 사용 사례와 장점

  • 간소화된 코드 : 읽기 쉬운 코드를 작성 가능.
  • 함수형 프로그래밍 : 람다 표현식을 통해 자바는 함수를 매개변수로 전달하고, 변수에 저장하는 함수형 프로그래밍 패러다임을 이해하고 사용가능.
  • 컬렉션 처리 : 람다 + 스트림 API를 함께 사용하며 매핑, 필터링, 요소 축소, 고급 컬렉션 처리 작업을 수행 가능.
  • 이벤트 처리 : 이벤트 리스너의 간결한 표현 가능.

매개변수가 없는 람다식

  • 함수형 인터페이스의 추상 메서드에 배개변수가 없을 경우 람다식 작성하기.
  • 실행문이 두개 이상일 경우에는 중괄호를 생략할 수 없고, 하나일 경우에만 생략할 수 있음.

매개변수가 있는 람다식

  • 함수형 인터페이스의 추상 메서드에 매개변수가 있을 경우 람다식 작성하기.
  • 매개변수를 선언할 때 타입은 생략할 수 있고, 구체적인 타입 대신에 var을 사용할 수 있음.
  • 매개변수가 하나일 경우에는 괄호를 생략 가능. 이때는 타입 또는 var을 붙일 수 없음.

리턴값이 있는 람다식

  • 함수형 인터페이스의 추상 메서드에 리턴값이 있을 경우 람다식 작성하기.
  • return문 하나만 있을 경우에는 중괄호와 함께 return 키워드를 생략 가능.
  • 리턴값은 연산식 또는 리턴값 있는 메서드 호출로 대체 가능.

메서드 참조

  • 메서드를 참조해 매개변수의 정보 및 리턴 타입을 알아내 람다식에서 불필요한 매개변수를 제거.

정적 메서드와 인스턴스 메서드 참조

  • 정적 메서드를 참조 시 클래스 이름 뒤에 :: 기호를 붙이고 정적 메서드 이름을 기술.
  • 인스턴스 메서드일 경우에는 객체를 생성한 다음 참조 변수 뒤에 ::기호를 붙이고 인스턴스 메서드 이름을 기술.

매개변수의 메서드 참조

  • 람다식에서 제공되는 a 매개변수의 메서드를 호출해서 b 매개변수를 매개값으로 사용.
  • a의 클래스 이름 뒤에::기호를 붙이고 메서드 이름을 기술.

생성자 참조

  • 객체를 생성하는 것. 람다식이 단순히 객체를 생성하고 리턴하도록 구성되면 람다식을 생성자 참조로 대치 가능.
  • 클래스 이름 뒤에 :: 기호를 붙이고 new 연산자를 기술.
  • 생성자가 오버로딩되어 여러 개가 있을 경우, 컴파일러는 함수형 인터페이스의 추상 메서드와 동일한 매개변수 타입과 개수를 가지고 있는 생성자를 찾아 실행.
  • 해당 생성자가 존재하지 않으면 컴파일 오류 발생.

※※※PLUS※※※

  • 중첩 클래스(클래스 내부에 선언한 클래스 - Nested Class)로부터 시작.
  • 특정 클래스만 관계를 맺을 경우에 중첩 클래스에 선언하는 것이 유지보수에 더 이점이 있음.
  • 클래스의 멤버를 쉽게 사용하고, 외부에는 중첩관계 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있음.
  • 선언 위치에 따라 두 분류로 나눌 수 있다.
    1. 클래스의 멤버로 선언되는 중첩 클래스 : 멤버 클래스
      class A{
         class B{...}
      } // A객체를 생성해야지만 B객체를 생성할 수 있음 : 인스턴스 멤버 클래스

      class A{
         static class B{...}
      } // A객체를 생성하지 않아도 B객체를 생성할 수 있음 : 정적 멤버 클래스
    2. 메소드 내부에서 선언되는 중첩 클래스 :  로컬 클래스
      class A{
         void method(){
            class B {.....}
         }
      }  // method 가 실행할 때만 B객체를 생성할 수 있음.
  • 중첩 인터페이스는 클래스의 멤버로 선언된 인터페이스를 말함.
  • 그럼 클래스 내부에 인터페이스를 선언하는 이유는 무엇인가
    1. 해당 클래스와 긴밀한 관계를 맺는 구현 객체를 만들기 위함.
      class A{
         public | private | [static] interface B{
         //상수 필드, 추상 메서드, 디폴트 메서드, 정적 메서드

    2. } // A객체를 생성해야지만 B객체를 생성할 수 있음 : 인스턴스 멤버 클래스

  • 익명 객체(익명 클래스)는 이름이 없는 클래스
  • 프로그램에서 일시적으로 한번만 사용되고 버려지는 객체(재사용되지 않는)
  • 프로그램 내에서 일시적으로 한번만 사용되는 객체의 경우
    • UI 이벤트, 스레드 객체
    • 재사용성이 필요없고, 유지보수의 편의성을 제공하려고 함

 

https://github.com/bottomsUp-99?tab=repositories

 

bottomsUp-99 - Overview

Backend Developer. bottomsUp-99 has 10 repositories available. Follow their code on GitHub.

github.com

 

728x90
반응형

'Java Study' 카테고리의 다른 글

데이터 입출력  (2) 2024.07.17
java.base 모듈  (0) 2024.07.13
제네릭(Generic)이란?  (1) 2024.07.10
JDBC 라이브러리  (0) 2024.07.07
예외 처리(Exception Handling)  (1) 2024.07.07