자바 람다식 튜토리얼
By on May 29, 2019
자바 람다식 소개
이 포스팅에서는 Java Lambda Express 에 대해 소개 합니다. Lambda 기능은 Java8에서 소개 되었는데 Functional Programming 을 하기 위한 첫번째 단계로 볼 수 있습니다. 클래스 없이 함수를 만들 수 있고 매개변수로 전달도 가능 하며 필요에 따라 언제든지 실행 할 수 있습니다. Java Lambda expressions 는 전달할 수 있는 익명 함수(Anonymous Class)의 간결한 표현입니다.
- 속성
- Anonymous class : 명시적 이름이 없기 때문에 익명으로 호출 할 수 있다.
- 간결 : Anonymous Class 의 경우에도 언급했듯이, 익명 클래스에 비해 작성 코드를 줄일 수 있다.
- 기능 : Lambda는 매개 변수 목록을 허용하고 본문을 가지며 예외도 throw 할 수 있다.
- 전달 : Lambda는 일반 매개 변수 처럼 다른 함수로 전달 될 수 있다.
자바 람다식 작성 하는 방법
간단한 기능을 수행 하는 코드를 작성하여 Lambda Expressions 을 이용하면 얼마나 간결하게 소스 코드를 줄일 수 있는지 비교합니다.
비교를 위해 학생 ID, NAME을 매개 변수로 포함하는 간단한 POJO 클래스를 만듭니다.
Student.java
public class Student{
private Long id;
private String name;
// standard setters and getters
}
POJO 응용 프로그램에서 정의한 객체를 비교하는 것은 매우 일반적인 프로그래밍 방법입니다.
두개의 Student 클래스 객체를 비교하려면 Comparator를 다음과 같이 만들 수 있습니다.
Comparator Anonymous Class
Comparator<Student> byId = new Comparator<Student>(){
@Override
public int compare(Student s1, Student s2){
return s1.getId().compareTo(s2.getId());
}
}
위 코드는 Anonymous Class로 간단한 Comparator를 구현 한 것이지만 Lambda를 이용했을때 동일한 코드가 어떻게 변화하는지 비교 할 수 있습니다.
Lambda
Comparator<Student> byId = (s1, s2) -> s1.getId().compareTo(s2.getId());
위 람다식은 -> 기호의 오른쪽에 단일 코드 블록으로 구성되어 있어 블록 람다식 이라고도 할 수 있습니다. 다음 코드는 더욱 간결한 소스 코드로 변환 한 예제 입니다.
Concise implementation of Lambda
Comparator<Student> byId = Comparator.comparing(Student::getId);
Lambda Expressions VS Anonymous Class
람다식을 사용하여 작성한 코드는 람다식과 완전히 동일한 익명 클래스를 사용하여 작성 할 수 있습니다.
예) Runnable을 입력으로 사용하는 클래스와 메소드로 비교 해보겠습니다. Runnable with Anonymous Class
Runnable runnable = new Runnable(){
@Override
public void run(){
System.out.println("Anonymous class implementation.");
}
};
runnable.run();
Lambda Runnable
Runnable runnable = () -> System.out.println("Lambda Expression.");
runnable.run();
예2) Comparator Interface 를 이용 하여 비교 해보 겠습니다.
Comparator Anonymous Class
List<Node> nodes = new ArrayList<Node>();
// Sort with inner Class
Collections.sort(nodes, new Comparator<node>(){
public int compare(Node n1, Node n2){
return n1.getValue().compareTo(n2.getValue());
}
}
Lambda Expression
Collections.sort(nodes, (Node n1, Node n2) -> n1.getValue().compareTo(n2.getValue()));
Collections.sort(nodes, (n1, n2) -> n1.getValue().compareTo(n2.getValue()));
_매개 변수 유형 추론
Functional Interface 작성 방법
Functional Interface는 단 하나의 Abstract Method 를 가질 수 있습니다.
- Print.java
@FunctionalInterface public Interface Print{ public abstract void print(); }
- PrintTest.java
public static void main(String[] args){ Print p = () -> System.out.println("print test!!"); p.print(); }
Java.util.stream 패키지에서의 Lambda
stream 에서의 Lambda식 활용
public void main(String args[]){
List<String> myList =
Arrays.asList("area", "block", "building", "city", "country");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
}
이 처럼 많은 부분에서 Lambda 식은 활용 될 수 있다. 아직 실제 서비스에서의 사용에는 Stream, Enum 정도에서 사용을 하고 있다. 가독성 부분에서 의견이 분분 한 것 같지만 매우 편한 방법임은 확실 한 것 같다.