함수의 개념을 중심으로 프로그래밍하는 언어. OOP는 어떻게 문제를 해결할 것인가에 집중하지만 함수형 프로그래밍은 무엇을 해결할지에 집중. 코드 재사용, 효율성 개선, 높은 가독성이 특징이다. 병렬처리에 유리하며 대규모 병렬 처리(빅데이터)나 분산처리 시스템에서 많이 사용된다. 대표적으로 Scala, Haskell, Clojure 등이 있다.
java는 OOP 객체지향 언어이지만 JDK 1.8부터 함수형 언어의 기능을 일부 추가했다.
: 함수(메서드)를 간단한 식(expression)으로 표현하는 방법.
람다는 익명함수, 이름이 없는 함수다. 반환 타입과 이름이 없고 -> 가 생긴다.
람다를 통해서 함수를 간단하고 명확하게 표현할 수 있다.
메서드는 클래스에 종속적이지만 람다는 람다 자체만으로 메서드 역할을 대신할 수 있다.
람다로 인해 메서드를 변수처럼 다룰 수 있다.(매개변수로 쓰이거나 결과값으로 반환 가능)
int max(int a, int b) { return a > b ? a : b;}
// 1. 메서드 이름과 반환 타입을 제거하고 ->를 추가한다.
(int a, int b) -> {a > b ? a : b;}
// 2. 반환 값이 있는 메서드는 return 대신 식으로 대신할 수 있다. 문장이 아니라 식이므로 ;를 생략 가능하다.
// {}중괄호 안의 문장이 하나면 생략 가능. 문장끝에 ;가 없어야한다. 여러 줄은 {} 생략 불가능
(int a, int b) -> a > b ? a : b
// 3. 매개변수의 타입을 추론 가능 시 생략가능(대부분 생략)
(a, b) -> a > b : a ? b
// 4. 매개변수가 하나일 때 매개변수 타입이 없으면 생략 가능
a -> a + 5
// 5. 매개변수가 없으면 ()로 표시한다
() -> (int)(Math.random() * 6)
interface MyFunction {
int max(int a, int b);
}
// 위처럼 함수형 인터페이스를 선언하고 아래는 main 메서드 안
Myfunction f = (a,b) -> a > b ? a : b; // 람다식, 익명객체를 f로 둠. 함수형 인터페이스를 타입으로 선언
int value = f.(3,5); // 람다식을 참조변수로 둬서 바로 사용
void method1(MyFunction f) // 이런식으로 람다 식을 매개변수로 쓰거나
return f // 반환값으로도 사용 가능
java.util.fuction 패키지에는 자주쓰이는 함수형 인터페이스가 미리 정의되어 있다.
T는 Type, R은 Return. 매개변수 개수가 2개면 Bi를 접두사로 붙이면 된다.
Predicate<Integer> p = i -> i< 100;
이런 식으로 람다식을 p에 할당해 p.test(99)로 쓸 수 있다.
컬렉션 프레임워크의 메서드에 함수형 인터페이스 람다식으로 적용 예시
Arraylist<Integer> list = new ArrayList<>();
... // 리스트에 0부터 9까지 넣었다 치면
list.forEach(i->System.out.println(i)); // 모든 요소에 action 수행
list.removeIf(x-> x%2==0 || x-> x%3==0); // 해당하는 조건(Predicate)를 삭제
list.replaceAll(i->i*10); // 모든 요소를 변환해서 대체
클래스이름::메서드이름
으로 쓸 수 있다.Fuction<String, Integer> f = (String s) -> Integer.parseInt(s);
Fuction<String, Integer> f = Integer::parseInt; // 위에걸 메세지 참조로 줄일 수 있다.
Function<String, MyClass> s = (i) -> new MyClass(i);
Function<String, MyClass> s = MyClass::new; // 위의 람다식을 메서드 참조로 간단히
// 배열 생성시
Function<Integer, int[]> f = x -> new int[x];
Function<Integer, int[]> f = int[]::new;