본문 바로가기

Education/인프런 워밍업 클럽(BE 0기)

인프런 워밍업 클럽 - BE 0기, 과제 #3

목차

    과제

    [키워드]

    익명 클래스 / 람다 / 함수형 프로그래밍 / @FunctionalInterface / 스트림 API / 메소드 레퍼런스

     

    [질문]

    • 자바의 람다식은 왜 등장했을까?
    • 람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?

    1. 자바의 람다식은 왜 등장했을까?

    람다식이 등장한 주 원인은 불필요한 코드를 줄이고, 가독성을 높이기 위해서이다.

    람다식은 익명 클래스를 사용할 때보다 더 쉽고 간결한 코드를 작성할 수 있게 해준다.

    람다를 사용하면 파라미터와 바디만으로 필요한 기능을 구현할 수 있다. 즉, 적은 타이핑으로 원하는 코드를 작성할 수 있다. 

    또한 정의된 곳에서만 사용되기 때문에 따로 메서드를 정의할 필요가 없어서 불필요한 메서드 생성을 줄일 수 있다.


    2. 람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?

    자바8 이전에는 인터페이스를 통한 익명 클래스나 익명 내부 클래스를 사용해서 함수형 프로그래밍을 구현했다.

    하지만 익명 클래스를 사용하면 코드가 복잡하고 가독성이 떨어지는 단점이 있다.

    자바8에서 람다식이 도입되어 함수형 프로그래밍을 더욱 쉽고 간결하게 표현할 수 있게 되었다.

     

    익명 클래스와 람다식 모두 익명으로 구현된 객체를 생성되는 데 사용되지만 익명 클래스는 주로 인터페이스나 추상 클래스를 구현하거나 확장할 때 사용되고, 람다식은 주로 함수형 프로그래밍 스타일을 지원하거나 간단한 함수를 정의할 때 사용한다.

     

    강의에서 배운 내용을 예로 들어보겠다. JdbcTemplate 클래스의 query 메서드를 사용할 때 RowMapper를 구현하는데 익명 클래스를 사용했다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        public List<UserResponse> getUsers() {
            String sql = "SELECT * FROM user";
            return jdbcTemplate.query(sql, new RowMapper<UserResponse>() {
                @Override
                public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException {
                    long id = rs.getLong("id");
                    String name = rs.getString("name");
                    int age = rs.getInt("age");
                    return new UserResponse(id, name, age);
                }
            });
        }
    cs

     

     

    RowMapper는 함수형 인터페이스이므로 메서드가 하나뿐인 함수형 인터페이스이기 때문에 람다식을 사용해서 간단하게 표현할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
        public List<UserResponse> getUsers() {
            String sql = "SELECT * FROM user";
            return jdbcTemplate.query(sql, (rs, rowNum) -> {
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                return new UserResponse(id, name, age);
            });
        }
    cs

     

    위의 코드에서 (rs, rowNum) -> {...} 부분이 람다식으로 작성된 코드이다. 해당 람다식은 query 메서드에 전달되는 RowMapper 인터페이스의 구현체로 동작한다.

     

    익명 클래스를 사용할 때는 클래스 정의와 객체 생성이 번거로운 반면, 람다식은 간단하게 함수를 표현할 수 있기 때문에 람다식을 사용하면 코드가 훨씬 간단해지고 가독성이 향상된다.

     

     

    람다식의 문법
    1. 인자 리스트(parameters): 파라미터 리스트를 가진다. 파라미터가 없는 경우 빈 괄호를 사용하며, 파라미터가 여러 개 인 경우 괄호 안에 파라미터를 쉼표로 구분하여 나열한다. 파라미터 타입을 생략할 수 있다. 생략할 경우 컴파일러가 파라미터의 타입을 추론한다. 일반적으로 람다식을 사용하는 문맥에서 이미 타입이 명확하게 지정되어 있거나 추론이 가능한 경우에 생략된다.
    2. 화살표(->): 파라미터 리스트와 실행 블록을 '->'로 구분한다. 이 화살표는 "인자가 이 블록을 실행한다"는 의미를 가진다.
    3. 실행블록(body): 실행될 코드 블록을 가진다. 한 줄짜리 블록인 경우 중괄호'{}'를 생략할 수 있다. 이 경우 화살표 오른쪽에 바로 표현식을 적는다. 여러 줄로 이루어진 블록의 경우에는 중괄호를 사용하여 블록을 정의하고, 각 줄마다 명식적으로 return 키워드를 사용하여 값을 반환할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    //람다식
    (int a, int b) -> a + b

    //파라미터 타입 생략
    (a + b) -> a + b

    //메서드
    int add(int a, int b) {
      return a + b;
    }
    cs