[Java] Java 8 에서 자주 만나는 것들 1
Lambda
람다 표현식은 메서드를 하나의 식으로 표현한 것을 말한다.
기존의 불필요한 코드를 줄여주고, 작성된 코드의 가독성을 높여준다. 람다 표현식을 사용하여 자바에서도 함수형 프로그래밍을 할 수 있게 되었다.
기본 사용 예시
1
2
3
4
5
6
7
8
9
private static void lambdaTest1() {
new Thread(new Runnable() {
public void run() {
System.out.println("전통적인 방식의 일회용 스레드 생성");
}
}).start();
new Thread(() -> System.out.println("람다 표현식을 사용한 일회용 스레드 생성")).start();
}
1
2
전통적인 방식의 일회용 스레드 생성
람다 표현식을 사용한 일회용 스레드 생성
함수형 인터페이스
함수형 인터페이스는 단 하나의 추상 메서드만을 가져야 한다. 또한, 어노테이션(@FunctionalInterface
)을 사용하여 함수형 인터페이스임을 명시할 수 있다.
1
2
3
4
5
6
7
8
9
private static void lambdaTest2() {
Calc minNum = (x, y) -> x < y ? x : y;
System.out.println(minNum.min(3, 4));
}
@FunctionalInterface
private interface Calc {
int min(int x, int y); // 오직 1개의 추상 메서드를 가진다.
}
1
3
메서드 참조
람다 표현식에서 불필요한 매개변수를 제거한 표현이다. 대신 ::
기호를 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private static void lambdaTest3() {
DoubleUnaryOperator oper;
oper = (n) -> Math.abs(n);
System.out.println(oper.applyAsDouble(-5));
oper = Math::abs;
System.out.println(oper.applyAsDouble(-5));
MyClass myClass = new MyClass();
// Function<Integer, Integer> func = (a) -> myClass.makeDouble(a);
Function<Integer, Integer> func = myClass::makeDouble; // 매개변수 제거
System.out.println(func.apply(10));
}
static class MyClass {
int makeDouble(int n) {
return n * 2;
}
}
1
2
3
5.0
5.0
20
::
에 대한 느낌이 오는가? 아니면, 갑자기 DoubleUnaryOperator
나 Function
과 같은 키워드가 나와서 당황스러운가?
위 예제는 람다 표현식을 변수에 담아서 apply
로 실행시키는 과정도 포함되어있다.
DoubleUnaryOperator
인터페이스는 한 개의 double 형 매개변수를 전달받아 한 개의 double 형 값을 반환하는 java.util.function 패키지에서 제공하는 함수형 인터페이스이다.
다시 말해 DoubleUnaryOperator
는 double형 매개변수를 가지고, double형 리턴타입을 가지는 함수를 담는 타입이라는 얘기다.
Javascript를 사용해봤다면 함수를 변수에 저장하는 것이 자연스럽게 느껴질 수 있다.
Function<T, R>
인터페이스에서 T
는 매개변수 타입, R
은 결과 타입이다. R apply(T t)
메소드는 함수를 실행시켜 결과를 받는다.
Function
은 DoubleUnaryOperator
보다 더 포괄적인 개념이 될 것이다.
그러면 매개변수가 없거나 리턴 값이 없는 경우는? 이라고 생각한다면 아래 표를 참조하길 바란다.
Function
이나 DoubleUnaryOperator
외에도 다양한 인터페이스를 Java에서 제공한다.
Interface Table
Supplier |
( ) | -> | x |
Consumer |
x | -> | ( ) |
Callable |
( ) | -> | x throws exception |
Runnable |
( ) | -> | ( ) |
Function |
x | -> | y |
BiFunction |
x,y | -> | z |
Predicate |
x | -> | boolean |
UnaryOperator |
x1 | -> | x2 |
BinaryOperator |
x1,x2 | -> | x3 |
생성자 참조
생성자 호출도 화살표(람다 표현식)로 표현할 수 있지만, 단순히 인스턴스를 생성하고 반환한다면 더욱 간단하게 표현할 수 있다.
1
2
3
4
5
6
7
private static void lambdaTest5() {
Function<Integer, double[]> func1 = a -> new double[a];
System.out.println(Arrays.toString(func1.apply(5)));
Function<Integer, double[]> func2 = double[]::new;
System.out.println(Arrays.toString(func2.apply(5)));
}
1
2
[0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0]
댓글 남기기