개발/Java

Java8 - Lamda ν‘œν˜„μ‹(expression)

daramii 2022. 4. 29. 17:57

Java8 이상을 μ‚¬μš©ν•œλ‹€λ©΄ λ°˜λ“œμ‹œ μ•Œκ³  μžˆμ–΄μ•Όλ§Œ ν•˜λŠ” "λžŒλ‹€"에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² λ‹€.

이 λžŒλ‹€ ν‘œν˜„μ‹μ„ μ΅ν˜€ 놓지 μ•ŠμœΌλ©΄ μ•žμœΌλ‘œ λ§Œλ“€μ–΄μ§€λŠ” μžλ°” μ½”λ“œλ₯Ό μ½λŠ” 데 맀우 어렀움을 κ²ͺ을 수 있기 λ•Œλ¬Έμ—, κΌ­ μ•Œμ•„λ‘κΈ°λ₯Ό κΆŒν•œλ‹€.

 

πŸ’‘Lamda ν‘œν˜„μ‹μ€ μ™œ λ§Œλ“€μ–΄μ‘Œμ„κΉŒ?

읡λͺ… 클래슀λ₯Ό μ‚¬μš©ν•˜λ©΄, 클래슀λ₯Ό μƒˆλ‘­κ²Œ λ§Œλ“œλŠ” 데 ν•„μš”ν•œ λΉ„μš©μ„ 쀄일 수 μžˆλ‹€λŠ” μž₯점이 μžˆμ§€λ§Œ, λ°˜λŒ€λ‘œ 가독성이 λ–¨μ–΄μ§€λŠ” λΆˆνŽΈν•¨μ΄ μžˆλ‹€. 이λ₯Ό λ³΄μ™„ν•˜κ³ μž λ§Œλ“€μ–΄μ‘Œλ‹€.

 

πŸ’‘Lamda ν‘œν˜„μ‹μ€ μ–Έμ œ μ“ΈκΉŒ?

이 ν‘œν˜„μ‹μ€ μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ†Œλ“œκ°€ "ν•˜λ‚˜"인 κ²ƒλ“€λ§Œ 적용 κ°€λŠ₯ν•˜λ‹€. κ·Έλž˜μ„œ, λžŒλ‹€ ν‘œν˜„μ‹μ€ 읡λͺ… 클래슀둜 μ „ν™˜μ΄ κ°€λŠ₯ν•˜λ©°, 읡λͺ… ν΄λž˜μŠ€λŠ” λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ μ „ν™˜μ΄ κ°€λŠ₯ν•˜λ‹€.

 

πŸ’‘Java에 μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€ 쀑, λ©”μ†Œλ“œκ°€ ν•˜λ‚˜μΈ μΈν„°νŽ˜μ΄μŠ€μ—λŠ” μ–΄λ–€ 것듀이 μžˆμ„κΉŒ?

β–Ά java. lang.Runnable
β–Ά java.util.Comparator
β–Ά java.io.FileFilter
β–Ά javauril.concurrent.Callable
β–Ά java.security.PrivilegedAction
β–Ά java.nio.file.PathMatcher
β–Ά java.lang.reflect.InvocationHandler

 

κ·Έλ ‡λ‹€λ©΄, 이제 ν‘œν˜„μ‹μ„ ν•œλ²ˆ μ‚΄νŽ΄λ³΄μž.

(int x, int y) -> x + y

() -> 43

(String s) -> { System.out.println(s); }

 

κΈ°λ³Έ λžŒλ‹€ ν‘œν˜„μ‹μ€ 3 λΆ€λΆ„μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

맀개 λ³€μˆ˜ λͺ©λ‘ ν™”μ‚΄ν‘œ 토큰(Arrow Token) 처리 식(리턴 κ°’)
(int x, int y) -> x + y

x와 y값을 λ°›μ•„μ„œ x+yλ₯Ό μ²˜λ¦¬ν•œ 값을 리턴해 μ€€λ‹€λŠ” μ˜λ―Έμ΄λ‹€. 

 

 

예제λ₯Ό ν†΅ν•΄μ„œ μ‚΄νŽ΄λ³΄μž.

λ‹€μŒ μ½”λ“œμ—λŠ” CalculateλΌλŠ” μΈν„°νŽ˜μ΄μŠ€κ°€ 있고, μ—¬κΈ°μ—λŠ” operationμ΄λΌλŠ” λ©”μ†Œλ“œ ν•˜λ‚˜κ°€ μ„ μ–Έλ˜μ–΄ μžˆλ‹€.

interface Calculate {
	int operation(int a, int b);
}

 

μœ„μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 읡λͺ… 클래슀둜 κ΅¬ν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

private void calculateClassic() {

	Caculate calculateAdd = new Calculate() {
            @Override
            public int operation (int a, int b) {
                return a+b;
            }
	};
	System.out.println(CalculateAdd.operation(1,2));
}

 

μœ„μ˜ calculateAddλΌλŠ” 읡λͺ… 클래슀 객체λ₯Ό λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ μ²˜λ¦¬ν•΄λ³΄μž.

private void calculateLambda() {

	Calculate calculateAdd = (a, b) -> a+b;
	System.out.println(calculateAdd.operation(1,2));

}

 

μ½”λ“œκ°€ μ—„μ²­ κ°„λ‹¨ν•΄μ‘Œλ‹€. 

 

이 λ©”μ†Œλ“œ λ‚΄μ—λŠ” a와 bλΌλŠ” λ³€μˆ˜κ°€ μ „ν˜€ μ„ μ–Έλ˜μ–΄ μžˆμ§€λ„ μ•ŠλŠ”λ°, μ΄λ ‡κ²Œ a와 bλ₯Ό μ‚¬μš©ν•˜κ³  κ·Έ 값을 λ”ν•˜κΈ°κΉŒμ§€ ν•˜κ³  μžˆλ‹€. κ·Έ μ΄μœ λŠ” CalculateλΌλŠ” μΈν„°νŽ˜μ΄μŠ€λŠ” λ©”μ†Œλ“œκ°€ ν•˜λ‚˜λ§Œ μ„ μ–Έλ˜μ–΄ 있기 λ•Œλ¬Έμ—, (a, b)라고 λ˜μ–΄ μžˆλŠ” 뢀뢄은 operation() λ©”μ†Œλ“œμ˜ int a와 int bλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ”λ‹€λŠ” μ˜λ―Έκ°€ λœλ‹€. (μ—¬κΈ°μ„œ a와 b처럼 λ³€μˆ˜ 이름을 μž„μ˜λ‘œ 선언해도 μ „ν˜€ 문제 μ—†λ‹€. x, y둜 해도 이상 없이 μˆ˜ν–‰λœλ‹€.)

 

μ΄λ ‡κ²Œ ν•˜λ‚˜λ§Œ μ„ μ–Έλ˜μ–΄ μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό Functional(κΈ°λŠ₯적) μΈν„°νŽ˜μ΄μŠ€λΌκ³  λΆ€λ₯Ό 수 μžˆλ‹€. λ§Œμ•½ 이 μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ†Œλ“œκ°€ μΆ”κ°€λœλ‹€λ©΄, 기쑴에 μž‘μ„±ν•΄λ‘μ—ˆλ˜ λžŒλ‹€μ‹μ— 컴파일 였λ₯˜κ°€ λ°œμƒν•œλ‹€. μ΄λŸ¬ν•œ ν˜Όλ™μ„ ν”Όν•˜κΈ° μœ„ν•˜μ—¬, μΈν„°νŽ˜μ΄μŠ€ μ„ μ–Έμ‹œ μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•  수 μžˆλ‹€.

 

Functional Interface

@FunctionalInterface
interface Calculate {
	int operation(int a, int b);
}

 

μ΄λ ‡κ²Œ μ„ μ–Έν•΄λ†“μœΌλ©΄, 단 ν•˜λ‚˜μ˜ λ©”μ†Œλ“œλ§Œ μ„ μ–Έν•  수 μžˆλ‹€. λ§Œμ•½ λ‘κ°œλ₯Ό μ„ μ–Έν•  μ‹œ, Calculate is not a functional interfaceλΌλŠ” 메세지가 뜨며 컴파일 였λ₯˜κ°€ λ°œμƒν•˜κ²Œ λœλ‹€. 

 

 

정리


λ§ˆμ§€λ§‰μœΌλ‘œ, μ—°μŠ΅μ‚Όμ•„ ν•΄λ‹Ή μ½”λ“œλ₯Ό λžŒλ‹€μ‹μœΌλ‘œ λ³€κ²½ν•΄λ³΄μž.

private void runCommonThread() {
	Runnable runnable = new Runnable() {
    	@Override
        public void run() {
        	System.out.println(Thread.currentThread().getName());
        }
    };
    new Thread(runnable).start();
}

 

μ •λ‹΅ (cf. λ§Œμ•½, λ©”μ†Œλ“œμ—μ„œ μ²˜λ¦¬ν•˜λŠ” 것이 μ—¬λŸ¬μ€„μΌ 경우 {}(μ€‘κ΄„ν˜Έ)λ₯Ό μ‚¬μš©ν•΄ 묢을 수 μžˆλ‹€.)

private void runCommonThread() {

	new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
    
}