[Java] Lambda - Understanding Lambda

반응형

이번 글에서는 lambda에 대해 알아보도록 하겠습니다.

1. Understanding Lambda

lambda란 java8에 추가된 functional programming을 지원하는 기술입니다.

lambda는 전통적인 OOP(Ojbect-Oriented-Programming)와는 전혀 다른 방식인 함수형 프로그래밍(Functional-Programming) 방법으로 프로그램을 작성합니다.

lambda를 사용해 프로그램을 작성하면 다음과 같은 이점을 가지게 됩니다.

• 함수형 프로그래밍 작성이 가능합니다.

• 읽기 쉽고 간결한 코드 작성이 가능합니다.

• API와 Librariy의 사용이 쉬워집니다.

• 병렬 processing으로 처리가 가능해집니다.

2. Functinal Programming vs OOP(Object-Oriented-Programming)

함수형과 전통적인 객체지향형 프로그래밍의 차이점을 한번 살펴보도록 하겠습니다. 😅

2-1) OOP(Object-Oriented-Programming)

먼저, 기존 OOP 방식의 프로그래밍에선 모든 기능들을 object 기반으로 작성했습니다. 따라서 모든 code blocks 들은 class & object 에 연관되어 있었습니다.

따라서 기존 자바 개발자들은 단순한 '기능'을 작성하는데도 이를 함수로 가지고 있는 class를 작성하고, 이를 인스턴스로 생성해 해당 인스턴스가 해당 '기능'을 수행하도록 명령했습니다.

위와 같은 상황에서, "난 클래스가 필요없어!, 난 그냥 단순한 로직일 뿐이야! 😂" 라고 울부짖어도 java7에서는 해결할 방법이 존재하지 않았습니다.

예를 들어 단순히 "Hello World"를 출력하는 '기능'이 필요할 경우에 기존 java7에서는 다음과 같이 프로그램을 작성했습니다.

public class Greeter {
    public void greet() {
        System.out.println("Hello World!");
    }

    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        greeter.greet();
    }
}

Greeter 클래스를 작성하고, 이를 사용해 Greeter 인스턴스를 생성해 greet 메서드를 호출하는 전형적인 OOP 방식의 프로그래밍입니다.

위와 같은 상황에서 만약에 greet 메서드가 항상 "Hello World"를 출력하는 것이 아니라 input 값을 argument로 받아서 input 값에 따라서 다른 '기능'을 수행하도록 한다면 아래와 같이 변경할 수 있습니다.

코드로 작성하면 아래와 같이 Interface 와 이를 구현한 클래스를 전달하는 방식으로 작성할 수 있습니다.

public class Greeter {
    public void greet(Greeting greeting) {
        greeting.perform();
    }

    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        HelloWorldGreeting helloWorldGreeting = new HelloWorldGreeting();
        greeter.greet(helloWorldGreeting);
    }
}

// action interface
interface Greeting {
    void perform();
}

// action implements class
class HelloWorldGreeting implements Greeting {
    @Override
    public void perform() {
        System.out.println("Hello Wolrd!");
    }
}

위와 같이 java7에서 특정 메서드에 '기능'을 전달하고, 해당 메서드는 전달받은 '기능'을 실행하도록 구현하는데는 많은 코드를 작성해야 했습니다.

lambda를 사용하면, 위와 같은 번거로움을 개선하고 기능을 구현한 클래스(HelloWorldGretting)가 아닌, '기능(action)'만 전달해 간결하고 가독성 있는 코드를 작성할 수 있습니다. 😎

2-2) Functional Programming

이번에는 동일한 기능을 lambda 식으로 작성해보겠습니다.

lambda 식으로 작성한 코드는 다음과 같습니다.

public class Greeter {
    public void greet(Greeting greeting) {
        greeting.perform();
    }

    public static void main(String[] args) {
        GreeterOOP greeter = new GreeterOOP();
        // using lambda expression
        greeter.greet(() -> System.out.println("Hello World!"));
    }
}

// action interface
interface Greeting {
    void perform();
}

훨씬.. 간결하네요? 😅

3. Function as value

조금더 자세히 살펴보겠습니다.

위와 같이 lambda식으로 작성한 '기능(action)'은 java8에서 마치 value 처럼 사용할 수 있습니다. 따라서 메서드의 인자값으로 해당 value를 넘겨줄 수 있는 것 입니다.

특정 '기능'을 수행하는 lambda 식을 임의의 변수에 할당하고, 이 변수들을 전달함으로써 단순히 '기능'만 작성된 코드를 주고 받고? 할 수 있다.. 정도로 이해하면 될 것 같습니다. 😅

aBlockOfCode = public void perform() {
    System.out.pritnln("Hello World!");
}

위와 같이 작성된 코드에서 필요없는 부분을 제거하면 lambda 식이 됩니다. 불필요한 부분은 다음과 같습니다.

• 접근 제한자 : function은 이 function을 소유한 모든 메서드에서 사용가능하므로 접근 제한자가 필요하지 않습니다.

• 리턴 타입 : lambda식에선 Java 컴파일러가 소스를 해석해 return 타입을 확인할 수 있도록 개선되었으므로 리턴 타입이 필요하지 않습니다.

• 함수명 : function을 담는 value의 스스로가 해당 function을 대표하므로 함수명이 필요하지 않습니다.

정리해보면 lambda 식은 다음과 같이 작성할 수 있습니다.

aBlockOfCode = () -> {
    System.out.println("Hello World!");
}

만약 function이 한줄로만 구성되어 있을 경우 코드 블럭을 추가적으로 제거할 수 있습니다.

• 코드 블럭 : { }

aBlockOfCode = () -> System.out.println("Hello World!");

추가 예제는 다음과 같습니다.

// input one parameter
doubleNumberFunction = (int a) -> a * 2;

// input two parameter
doubleNumberFunction = (int a, int b) -> a + b;

// function has more than one line
safeDivideFunction = (int a, int b) -> {
    if(b == 0) return 0;
    return a / b;
}

추천서적

 

이것이 자바다:신용권의 Java 프로그래밍 정복

COUPANG

www.coupang.com

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음


반응형

댓글

Designed by JB FACTORY