본문 바로가기
카테고리 없음

[자바] 람다 표현식의 장·단점 및 해결 방안

by 피크인사이트 2024. 2. 21.
반응형

자바 8에서 처음 도입된 람다 표현식은 자바 생태계에 혁명적인 변화를 가져왔습니다.

람다 표현식은 코드의 간결함과 가독성을 높이는 데 큰 장점이 있기도 하지만, 동시에 몇 가지 단점도 존재하며 이를 해결하기 위한 방안이 필요합니다.

이번 글에서는 람다 표현식의 장점과 단점 그리고 단점에 대한 보완 대책도 사례를 들어 살펴보도록 하겠습니다.


람다 표현식

[람다 표현식의 장점]

1. 간결하다

람다 표현식의 주요 장점 중 하나는 코드의 간결함입니다.

이로 인해 코드의 가독성이 높아지고 코드 중복이 감소하여, 코드의 재사용성과 유지보수성이 향상됩니다.

간단한 예시로 리스트의 각 요소를 출력하는 코드를 들 수 있습니다.

기존의 방법은 for 문을 사용하여 각 요소를 반복적으로 출력하는 것이 일반적이었습니다.

그러나 람다 표현식을 사용하면 코드를 매우 간결하게 작성할 수 있습니다.

//기존 방법: 
List names = Arrays.asList("John", "Jane", "Doe");
    for (String name : names) { 
    System.out.println(name); 
    }
    
//람다 표현식 사용: 
List names = Arrays.asList("John", "Jane", "Doe"); 
names.forEach(name -> System.out.println(name));

 

2. 함수형 프로그래밍 지원

람다 표현식의 장점은 함수형 프로그래밍을 지원한다는 점입니다.

람다 표현식은 함수를 일급 객체로 취급하며, 이를 통해 함수를 변수에 저장하거나, 다른 함수의 인자로 전달하거나, 함수의 결과로 반환하는 등의 작업을 할 수 있기 때문에 코드의 유연성을 크게 향상시킵니다.

 

또한, 람다 표현식은 '고차함수'를 지원합니다.

고차함수는 함수를 인자로 받거나, 결과로 반환하는 함수를 말하는데, 이를 통해 함수의 조합이나 재사용이 쉬워집니다.

다음 예시 코드는 기존 방식과 람다 표현식을 사용하여 버튼 클릭 이벤트를 처리하는 방법의 비교입니다

// 기존 방식
Button button = new Button(); //
button.addActionListener(new ActionListener() {
  @Override  
  //
 public void actionPerformed(ActionEvent e) {
 //
 System.out.println("Button clicked!");


// 람다 표현식
button.addActionListener(e -> System.out.println("Button clicked!"));

 기존 방식에서는 익명 내부 클래스를 사용하여 ActionListener 인터페이스를 구현하고, actionPerformed 메서드를 오버라이딩하여 버튼 클릭 시 실행될 동작을 정의합니다.

람다 표현식에서는 람다 표현식 e -> System.out.println("Button clicked!")을 사용하여 버튼 클릭 시 실행될 동작을 직접 정의합니다.

이때, ActionListener 인터페이스에는 단 하나의 추상 메서드인 actionPerformed 메서드가 존재하기 때문에 람다 표현식을 사용할 수 있습니다.

 

3.병렬 처리 용이

람다 표현식은 병렬 처리를 보다 간편하게 만들어줍니다.

이를 설명하기 위해 간단한 예시를 살펴보겠습니다.

배열의 모든 요소의 합을 계산하는 작업을 병렬로 처리하고자 한다고 가정할 경우, 기존의 방식으로는 반복문을 사용하여 각 요소를 순차적으로 더해야 했습니다.

그러나 람다 표현식을 사용하면 이 작업을 간단하게 병렬로 처리할 수 있습니다.

 

int[] array = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

// 기존 방식: 순차 처리
int sum = 0; //
for (int i : array) {
 sum += i; //
}
System.out.println("sum (sequential): " + sum);


// 람다 표현식을 사용한 병렬 처리
sum = Arrays.stream(array).parallel().sum();
System.out.println("Sum (parallel): " + sum);

 위 코드에서는 배열의 요소를 병렬로 처리하여 합을 계산하는 예시입니다.

Arrays.stream(array).parallel() 부분에서 parallel() 메서드를 호출하여 병렬 스트림을 생성합니다.

이후 sum() 메서드를 호출하여 모든 요소를 병렬로 더하고 결과를 반환합니다.


[람다 표현식의 단점]

람다 표현식은 많은 장점을 갖고 있지만 다음과 같이 몇 가지 단점도 존재합니다

1. 가독성 감소

복잡한 람다 표현식은 코드의 가독성을 저하시킬 수 있습니다.

특히 긴 람다 표현식이나 복잡한 람다 표현식을 남용하는 경우 코드의 이해가 어려워질 수 있습니다.

2.디버깅 어려움

람다 표현식은 익명 함수로서 디버깅하기 어려울 수 있습니다.

스택 트레이스에서 람다 표현식의 이름이 나타나지 않거나, 람다 표현식 내부의 변수나 상태를 쉽게 추적하기 어려울 수 있습니다.

3. 클래스 로딩 오버헤드

람다 표현식은 함수형 인터페이스의 인스턴스를 생성하기 위해 내부적으로 익명 클래스를 생성합니다. 이로 인해 클래스 로딩 및 인스턴스화 오버헤드가 발생할 수 있습니다.

4. 불변성 부족

람다 표현식 내부에서 외부 변수를 참조하는 경우, 해당 변수는 사실상 final 또는 effectively final이어야 하는데, 이로 인해 불변성 유지가 어려운 경우가 발생할 수 있습니다.

5. 메모리 사용량 증가

람다 표현식은 추가적인 객체 생성 및 메모리 사용량을 유발할 수 있습니다. 특히 람다 표현식이 자주 사용되고, 각각의 인스턴스가 많은 메모리를 차지하는 경우에는 이러한 오버헤드가 눈에 띌 수 있습니다.


[람다 표현식의 단점 최소화 방안]

람다 표현식의 단점을 최소화하기 위해 다음과 같이  몇 가지 방안을 고려할 수 있습니다.

1. 가독성을 유지하고 복잡성을 줄이기

람다 표현식을 작성할 때 가독성을 유지하고 복잡성을 최소화하는 것이 중요합니다.

긴 람다 표현식이나 복잡한 람다 표현식은 분리하여 메서드로 추출하거나, 간단한 표현식으로 대체하는 방법을 고려하여야 합니다

2. 디버깅 및 추적을 용이하게 하기

람다 표현식을 사용할 때는 가능한 한 간단하고 명확한 표현식을 사용하여 디버깅 및 추적을 용이하게 합니다. 람다 표현식 내부에서 외부 변수를 참조할 때는 해당 변수를 final 또는 effectively final로 만들어서 불변성을 유지합니다.

3. 메모리 사용량 최적화

람다 표현식을 사용할 때 불필요한 객체 생성을 최소화하고, 재사용 가능한 람다 표현식은 변수에 저장하여 반복적으로 사용하도록 합니다. 또한, 람다 표현식을 사용하는 곳이나 빈도에 따라 메모리 사용량을 최적화하는 방안을 고려합니다.

4.적절한 사용 상황 파악

람다 표현식은 특히 간결한 코드를 작성하고 함수형 프로그래밍 스타일을 적용할 때 유용하지만, 모든 상황에서 사용하는 것이 항상 바람직한 것은 아닙니다. 따라서 람다 표현식을 적절한 상황에서만 사용하여야 합니다.


마치며

 지금까지 살펴본 바와 같이 자바 생태계에 혁명적인 변화를 가져왔다고 평가받는 람다 표현식을 통하여 간결한 코드를 작성할 수 있으며, 함수형 프로그래밍의 장점을 활용하여 병렬 처리와 비동기 프로그램을 보다 쉽게 구현할 수 있게 되었습니다.

또한, 스트림 API와 함께 사용되면서 컬렉션 처리가 더 간편해졌고, 코드의 가독성과 유지보수성이 향상되었습니다.

하지만 람다 표현식의 단점도 존재하기 때문에 위에서 제시한 방안들을 고려하여 단점을 최소화하여 코드의 품질과 유지보수성을 유지하도록 하여야 할 것입니다.

반응형