본문 바로가기

이론/알고리즘&자료구조&Java

[Java8] 자바의 람다 표현식 - 자바로도 함수형 프로그래밍을 할 수 있다

함수형프로그래밍

함수의 조합으로 작업을 수행함. 작업이 이루어지는 동안 작업에 필요한 데이터와 상태는 변하지 않음.

  • 순수함수(Pure function): 외부에 아무런 영향을 미치지 않는 함수

  • 고계함수(Higher-order function): 함수를 하나의 값으로 간주하여 함수의 인자 혹은 반환 값으로 사용할 수 있는 함수

함수형 프로그래밍의 함수는 순수함수로서 외부에 아무런 영향을 주지 않는 선에서 자신의 로직을 처리하여 결과를 반환하는 역할을 한다. 이 결과 값을 얻는 것이 이 함수를 호출한 목적이다.

람다표현식


메소드를 하나의 식으로 표현한 것

전통적인 쓰레드 구현 코드

public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread");

}
}).start();
}

람다 표현식 코드

new Thread(()-> {System.out.println("thread");}).start();

Runnable interface의 경우 인자가 없는 추상메소드를 하나만 가지고 있기 때문에 이와 같이 생략할 수 있다

@FunctionalInterface

두 인자의 곱을 반환해주는 인터페이스가 있을 때,

public interface Ex {
public int mul(int a,int b);
}
public class Main {
public static void main(String[] args) {
Ex ex=(int a,int b) -> a*b;
System.out.println(ex.mul(1, 23));
}
}

이와 같이 사용할 수 있다.

그러나 프로그램을 개발하다보면 람다식 사용을 위한 인터페이스(Ex)가 람다식으로 사용되어지고 있는지의 여부를 모두가 파악하는 것은 쉽지 않다. 따라서, 누군가 해당 인터페이스에 새로운 추상 메소드를 추가할 수도 있는데, 그렇게 되면 인터페이스에는 오류가 나지 않지만, 메인클래스에는 오류가 발생하게 된다.

이러한 상황을 방지하기 위해 사용하는 어노테이션이 @functionalInterface 이다. 이 어노테이션을 사용하면 람다식으로 사용되고 있는 인터페이스에 두개 이상의 추상메소드를 추가하는 순간 유효하지 않다는 오류를 알려주고, 컴파일 수준에서 확인할 수 있으며 명시적으로 람다식으로 사용되고 있음을 표시할 수 있다.

람다 표현식을 사용하여 하나의 추상메소드를 매우 간편하게 다르게 구현할 수 있다

public interface Ex {
public int calc(int a,int b);
}

public class Main {

public static void main(String[] args) {
//타입 생략 가능
Ex add=(a,b) -> a+b;
Ex mul=(a,b) -> a*b;
Ex sub=(a,b) -> a-b;
Ex div=(a,b) -> a/b;

System.out.println(add.calc(5, 3));
System.out.println(mul.calc(5, 3));
System.out.println(sub.calc(5, 3));
System.out.println(div.calc(5, 3));

}

}

Comprator 인터페이스의 람다식 작성

public class Member {
String name;

public Member() {
this.name="default";
}
public Member(String name) {
this.name=name;
  }
public final static Comparator<Member> compareName = (l, r) -> l.name.compareTo(r.name);

}

public class Main {

public static void main(String[] args) {

Member member1=new Member("dabc");
Member member2=new Member("bce");
Member member3=new Member("cde");
Member[] members= {member1, member2, member3};
Arrays.sort(members, Member.compareName);

for(Member m:members) {
System.out.println(m.name);
}
}

}

Stream API


https://wraithkim.wordpress.com/2017/04/13/java-8-%EC%8A%A4%ED%8A%B8%EB%A6%BC-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC/

대부분의 스트림 연산들은 람다 표현식을 매개변수로 받아 연산들이 서로 간섭하지 않도록 한다