Backend/☕️ Java

자바 람다식, lambda expression

Hugehoo 2020. 11. 25. 17:26

람다식 도입 배경

(문제점) 자바는 메서드를 매개변수로 전달하지 못한다.

메서드를 매개변수로 전달하기 위해선 인스턴스 생성 후(인스턴스화)에 해당 메서드를 호출해야 하는 식이었다.

 

인터페이스가 가진 메소드를 즉흥적(인스턴스화를 거치지 않고)으로 사용하는 것이 목적

 

(해결책) 메서드를 매개변수로 전달하기 위해 자바8에서 도입된 기능이 람다식이다.

인스턴스화를 거친 후에 메소드를 전달할 수 있는 불편한 점을 람다식으로 해결한다.

 

람다 표현식

// 람다 표현식
(매개변수 목록) -> {
	
    	실행문
    
    }

 

 

예시 1)

동일한 패키지 내에서 Car, CarExam 클래스 파일 생성

 

Car.java

package lambda;

public class Car {

    public String name;
    public int capacity;
    public int price;
    public int age;

    public Car(String name, int capacity, int price, int age) {
        this.name = name;
        this.capacity = capacity;
        this.price = price;
        this.age = age;
    }

    public String toString(){
        return name;
    }

    public static void main(String[] args) {
        Car car = new Car("new Model", 4, 3000, 0);
        System.out.println(car.toString());
    }
}

 

CarExam.java

import java.util.ArrayList;
import java.util.List;

public class CarExam {
	public staic void main(String[] args){
    	List<Car> cars = new ArrayList<>();
		cars.add(new Car("작은차", 2, 800, 3));
		cars.add(new Car("봉고차", 12, 1500, 8));
		cars.add(new Car("중간차", 5, 2200, 0));
		cars.add(new Car("비싼차", 5, 3500, 1));
        
        
        // CarExam carExam = new CarExam();
        // carExam.printCar()로 쓸 수도 있지만, printCar을 static으로 선언하면 아래처럼 바로 사용가능
        printCar(cars, (Car car) -> {
        			return car.capacity >= 4;
						}
				);
		}
        
        public static void printCar(List <Car> cars, CheckCar tester){
        	for (Car car: cars) {
            	if(teste.test(car)) { // test 메소드의 내용은 위에서 람다표현식으로 정의
                	System.out.println(car);
				}
			}
		}
        
        // 인터페이스, test메소드, 인자: Car형의 car 필드
        interface CheckCar{
        	boolean test(Car car);
		}
}

                
		

 

위에서 람다 표현식의 형태는 (매개변수 목록) -> {실행문} 임을 명시해뒀다.

예시 1의 람다식에서는 (매개변수 목록) 부분에 (Car car)이 명시됐다 ( ∵ Car car는 인터페이스의 메소드 test의 매개변수로 사용됨)

printCar(cars, (Car car) -> {
	return car.capacity >= 4;
	});
}

 

 

예시 2)

Compare 인터페이스 (메소드를 하나만 가지는 인터페이스를 함수형 인터페이스라 부른다)

public interface Compare{
	public int compareTo(int value1, int value2);
}

 

Compare Exam

public class CompareExam {

    public static void exec(Compare compare){
    int n = 1;
    int m = 2;
    
    int total = compare.compareTo(n, m);
    System.out.println(total);
    
    }

    public static void main(String[] args) {
    	exec((i,j) -> {
        	return i + j;
            }
            ); 
     }
        
}

- exec 메소드는 Compare 인터페이스를 매개변수로 받아들인 후 해당 인터페이스를 사용

- 해당 인터페이스의 메소드는 메인 메소드에서 람다식으로 정의

- 이렇게 하면, Compare 클래스를 따로 인스턴스화 할 필요없이, compareTo메소드만 즉각적으로 구현하여 사용할 수 있다.

 

결론

결국 람다를 한줄로 나타내면 "메소드를 하나의 식(Expression)으로 표현한 것"이다. (하나의 식이지 한줄의 식이 아님)

인터페이스가 가진 메소드를 간편하게 즉흥적으로 구현, 사용하는 것이 목적