λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Java

[Java] - @FunctionalInterface ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

by 주발2 2021. 2. 11.
λ°˜μ‘ν˜•

 μ•ˆλ…•ν•˜μ„Έμš”~ 이전에 μš΄μ˜ν•˜λ˜ λΈ”λ‘œκ·Έ 및 GitHub, 곡뢀 λ‚΄μš©μ„ μ •λ¦¬ν•˜λŠ” Study-GitHub κ°€ μžˆμŠ΅λ‹ˆλ‹€!

 λ„€μ΄λ²„ λΈ”λ‘œκ·Έ

 GitHub

Study-GitHub

 πŸ”


βœ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ - @FunctionalInterface

μ•ˆλ…•ν•˜μ„Έμš”~ μ΄λ²ˆμ— 정리할 λ‚΄μš©μ€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μž…λ‹ˆλ‹€.

 

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ–˜κΈ°ν•˜κΈ° 전에 일급 객체(First Class Citizon)에 λŒ€ν•΄ κ°„λ‹¨νžˆ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

 

First Class Citizon

 First Class Citizon 은 μ•„λž˜μ˜ 속성듀을 λͺ¨μ£Ό λ§Œμ‘±ν•΄μ•Ό ν•©λ‹ˆλ‹€.

     λ³€μˆ˜μ— 값을 ν• λ‹Ήν•  수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

     ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ€„ 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

     ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ΄ 될 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

​

Java에 λ©”μ„œλ“œλŠ” μœ„ 쑰건의 λͺ¨λ‘λ₯Ό λ§Œμ‘±ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 일급객체가 μ•„λ‹ˆκ³ ,

λ”°λΌμ„œ JavaλŠ” ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄κ°€ μ•„λ‹™λ‹ˆλ‹€.

ν•˜μ§€λ§Œ, Java8μ—μ„œλŠ” ν•¨μˆ˜λ₯Ό μΌκΈ‰κ°μ²΄μ²˜λŸΌ λ‹€λ£° 수 있게 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

 

@FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ€ μžλ°”8μ—μ„œ μΆ”κ°€λœ μ–΄λ…Έν…Œμ΄μ…˜μž…λ‹ˆλ‹€.

​

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€(Functional Interface)λŠ” 좔상 λ©”μ„œλ“œκ°€ λ”± ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§ν•©λ‹ˆλ‹€.

그리고 λžŒλ‹€μ‹μ€ μ΄λŸ¬ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό 기반으둜만 μž‘μ„±μ΄ 될 수 μžˆμŠ΅λ‹ˆλ‹€.

​

β˜… 즉, ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” μ΄μœ λŠ” λžŒλ‹€μ‹μ€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œλ§Œ 접근이 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•©λ‹ˆλ‹€! β˜…

β€‹κ°„λ‹¨ν•œ μ˜ˆμ‹œλ₯Ό 톡해 좔상 λ©”μ„œλ“œκ°€ ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λž€ 어떀것인지 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

​

​

​

 

• λ§€κ°œλ³€μˆ˜κ°€ 있고 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” λžŒλ‹€μ‹

μœ„ μ˜ˆμ œμ—μ„œ 보듯 μ—¬λŸ¬κ°€μ§€μ˜ ν‘œν˜„μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

​

 

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

μ€„μž„μ΄ μ—†λŠ” λžŒλ‹€μ‹μ€ μœ„μ™€ κ°™μŠ΅λ‹ˆλ‹€. λ§€κ°œλ³€μˆ˜ 정보에 μ†Œκ΄„ν˜Έλ₯Ό ν•˜κ³  λ©”μ†Œλ“œ λͺΈμ²΄μ—λŠ” μ€‘κ΄„ν˜Έλ₯Ό ν•©λ‹ˆλ‹€.

​

 

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

(s) -> System.out.println(s);

μ€‘κ΄„ν˜Έλ₯Ό μƒλž΅ν• λ•ŒλŠ” ν•΄λ‹Ή λ¬Έμž₯의 끝에 μœ„μΉ˜ν•œ μ„Έλ―Έμ½œλ‘ λ„ ν•¨κ»˜ μƒλž΅ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 

그리고 μœ„ μ½”λ“œμ—μ„œ λ§€κ°œλ³€μˆ˜μ˜ 정보에 λŒ€ν•΄ sκ°€ Stringν˜• μž„μ€ 컴파일러의 μž…μž₯μ—μ„œ μœ μΆ”κ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ 두 번째 λ°©μ‹μ²˜λŸΌ, λ§€κ°œλ³€μˆ˜μ˜ μžλ£Œν˜• 정보(String)도 μƒλž΅μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

​

 

s -> System.out.println(s)

그리고 λ§€κ°œλ³€μˆ˜κ°€ μœ„μ™€ 같이 ν•˜λ‚˜μΌ κ²½μš°μ—λŠ” λ‹€μŒκ³Ό 같이 μ†Œκ΄„ν˜Έλ„ μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

;

​

System.out::println

λ§ˆμ§€λ§‰ ν‘œν˜„μ—μ„œ :: 은 λ©”μ†Œλ“œ μ°Έμ‘°(Method References)λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

 

 

βœ” λ©”μ†Œλ“œ μ°Έμ‘°(Method References)λž€? 

λžŒλ‹€μ‹λ„ κ²°κ΅­ λ©”μ†Œλ“œμ˜ μ •μ˜μ΄λ―€λ‘œ λ‹€μŒκ³Ό 같이 생각해 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

"이미 μ •μ˜λ˜μ–΄ μžˆλŠ” λ©”μ†Œλ“œκ°€ μžˆλ‹€λ©΄, 이 λ©”μ†Œλ“œμ˜ μ •μ˜κ°€ λžŒλ‹€μ‹μ„ λŒ€μ‹ ν•  수 μžˆμ§€ μ•Šμ„κΉŒ?"

μ‹€μ œ λ©”μ†Œλ“œ μ •μ˜λŠ” λžŒλ‹€μ‹μ„ λŒ€μ‹ ν•  수 μžˆλŠ”λ°, 이λ₯Ό "λ©”μ†Œλ“œ μ°Έμ‘°(Method References)"라고 ν•©λ‹ˆλ‹€.
μ½”λ“œμ˜ 양을 쀄이고, 가독성도 κ°œμ„ λœλ‹€λŠ” μ μ—μ„œ 'λ©”μ†Œλ“œ μ°Έμ‘°'λŠ” λžŒλ‹€μ‹μœΌλ‘œ 쀄어든 μ½”λ“œμ˜ 양을 쑰금 더 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.
ClassName::MethodName

좜처: μœ€μ„±μš°μ˜ μ—΄ν˜ˆ Java ν”„λ‘œκ·Έλž˜λ°
Consumer<List<Integer>> c = l -> Collections.reverse(l); // μ €μž₯ μˆœμ„œ 뒀집기
Consumer<List<Integer>> c = Collections::reverse();      // μœ„μ™€ λ™μΌν•œ κ²°κ³Ό

Function<char[], String> f = ar -> { return new String(ar); };
Function<char[], String> f = String::new;  // μƒμ„±μž μ°Έμ‘°



 

• λ§€κ°œλ³€μˆ˜κ°€ 있고 λ°˜ν™˜ν•˜λŠ” λžŒλ‹€μ‹

μœ„μ˜ μ˜ˆμ œμ—μ„œ λ“±μž₯ν•œ λžŒλ‹€μ‹μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

​

(a, b) -> { return a+b; };

λ©”μ„œλ“œ λͺΈμ²΄μ— ν•΄λ‹Ήν•˜λŠ” λ‚΄μš©μ΄ return 문일경우, κ·Έ λ¬Έμž₯이 ν•˜λ‚˜μ΄λ”λΌλ„ μ€‘κ΄„ν˜Έμ˜ μƒλž΅μ΄ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μœ„μ˜ λžŒλ‹€μ‹μ€ λ‹€μŒκ³Ό 같은 ν‘œν˜„μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

 

(a, b) -> a + b;

μœ„μ˜ 경우 λ©”μ„œλ“œ λͺΈμ²΄μ— 연산이 λ“±μž₯ν•˜λŠ”λ°, 이 연산이 μ§„ν–‰λ˜λ©΄ κ·Έ 결과둜 값이 λ‚¨κ²Œλ©λ‹ˆλ‹€.

그러면 이 값은 λ³„λ„λ‘œ λͺ…μ‹œν•˜μ§€ μ•Šμ•„λ„ λ°˜ν™˜μ˜ λŒ€μƒμ΄ λ©λ‹ˆλ‹€.

λ”°λΌμ„œ return문이 λ©”μ„œλ“œ λͺΈμ²΄λ₯Ό μ΄λ£¨λŠ” μœ μΌν•œ λ¬Έμž₯이라면 μœ„μ™€ 같이 μƒλž΅ν•΄μ„œ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

 

 

κ°„λ‹¨ν•˜κ²Œ λžŒλ‹€μ‹μ„ 톡해 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ μ˜ˆμ‹œμ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜λŠ”λ°μš”,

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ‹€μ‹œ μ •μ˜ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€(Functional Interface)λŠ” 좔상 λ©”μ„œλ“œκ°€ 단 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§ν•©λ‹ˆλ‹€.
그리고 λžŒλ‹€μ‹μ€ μ΄λŸ¬ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό 기반으둜만 μž‘μ„±μ΄ 될 수 μžˆμŠ΅λ‹ˆλ‹€.

​

λ‹€μŒμ€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ™€ ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ΄ λΆ™μ–΄ μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€μ˜ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

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

 

 

@FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ λΆ€ν•©ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•œ μ–΄λ…Έν…Œμ΄μ…˜ νƒ€μž…μž…λ‹ˆλ‹€.

​

λ§Œμ•½ μœ„ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ λ‘˜ μ΄μƒμ˜ 좔상 λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•œλ‹€λ©΄, μ΄λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— 컴파일 였λ₯˜λ₯Ό λ°œμƒν•©λ‹ˆλ‹€.

Invalid '@FunctionalInterface' annotation; Calculate is not a functional interface

@FunctionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ΄ νƒ€λ‹Ήν•˜μ§€ μ•Šκ³ , Calculate λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλΌκ³  λ§ν•©λ‹ˆλ‹€.

​

​

ν•˜μ§€λ§Œ, staticμ΄λ‚˜ default 선언이 뢙은 λ©”μ„œλ“œμ˜ 경우 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ—λŠ” μ•„λ¬΄λŸ° 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

​

λ”°λΌμ„œ λ‹€μŒ μΈν„°νŽ˜μ΄μŠ€λ„ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λΌκ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

μΈν„°νŽ˜μ΄μŠ€λŠ” μ œλ„€λ¦­μœΌλ‘œ μ •μ˜ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 방식은 μžλ°” 8 μ—μ„œλΆ€ν„°λŠ” μ•„μ£Ό ν”ν•œ 일이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

​

μ™œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œλ„€λ¦­μœΌλ‘œ μ •μ˜ν•˜λŠ”κ²ƒμ— λŒ€ν•΄ μ„€λͺ…을 ν•˜λŠλƒ?

-> 이후에 λ‚˜μ˜¬ λ„€ μ’…λ₯˜μ˜ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€!

μœ„μ˜ μ„Έ λ¬Έμž₯의 λžŒλ‹€μ‹μ€ λ™μΌν•˜μ§€λ§Œ, μ°Έμ‘°λ³€μˆ˜μ˜ μžλ£Œν˜•μ΄ λͺ¨λ‘ λ‹€λ₯΄λ―€λ‘œ μ „ν˜€ λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€μ˜ μƒμ„±μœΌλ‘œ μ΄μ–΄μ§‘λ‹ˆλ‹€.

μ •μˆ˜ν˜• λ§μ…ˆμ„ ν•˜λŠ” μΈμŠ€ν„΄μŠ€, λ¬Έμžμ—΄, μ‹€μˆ˜ν˜•μ„ μ°Έμ‘°ν•˜λŠ” 각 μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ©λ‹ˆλ‹€.

 

 

 

βœ” μžλ°”μ— μ •μ˜λ˜μ–΄ μžˆλŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

  • Function<T, R>

μœ„ 사진은 Function<T, R> 의 λ‚΄λΆ€ μ½”λ“œμ€‘ 일뢀 μž…λ‹ˆλ‹€.

​

μœ„ μΈν„°νŽ˜μ΄μŠ€μ—λŠ” λ‹€μŒκ³Ό 같은 좔상 λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

R apply(T t);   // 전달 μΈμžμ™€ λ°˜ν™˜ 값이 λͺ¨λ‘ μ‘΄μž¬ν•  λ•Œ

apply λΌλŠ” λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•˜κ³ , μΈμžλ‘œλŠ” μ–΄λ–€ νƒ€μž…μ˜ T(μ œλ„€λ¦­) 을 λ°›κ³  R(μ œλ„€λ¦­) 을 λ¦¬ν„΄ν•©λ‹ˆλ‹€.

 

 

βœ” Function 예제

package other;

import java.util.function.Function;

public class FunctionalInterfaceExamples {

    public static void main(String[] args) {
        Function<String, Integer> toInt = new Function<String, Integer>(){

            @Override
            public Integer apply(String t) {
                return Integer.parseInt(t);
            }
        };
        
        // Function<String, Integer> toInt = Integer::parseInt;

        Integer number = toInt.apply("100");
        System.out.println("number: " + number);
    }
}

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μΈ Function<T, R>을 μ‚¬μš©ν•΄ λ‚΄λΆ€μ˜ apply() λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•œ μ½”λ“œμž…λ‹ˆλ‹€.

​

Function<String, Integer> toInt = new Function<String, Integer>() {
    @Override
    public Integer apply(String t) {
        return Integer.parseInt(t);
    }
};

μœ„ 예제λ₯Ό λ¦¬νŒ©ν† λ§ ν•΄μ„œ λžŒλ‹€ ν‘œν˜„μ‹μœΌλ‘œ 변경해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

β‘  λ¨Όμ € new λΆ€ν„° λ©”μ„œλ“œ 이름(apply)κΉŒμ§€ λͺ¨λ‘ μ œκ±°ν•˜κ³ , λ§ˆμ§€λ§‰ μ€‘κ΄„ν˜Έλ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

Function<String, Integer> toInt = (String t) {
    return Integer.parseInt(t);
};

 

β‘‘ κ·Έ ν›„ λ§€κ°œλ³€μˆ˜μ™€ μ€‘κ΄„ν˜Έ 사이에 ->(λžŒλ‹€ν‘œν˜„μ‹) λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

Function<String, Integer> toInt = (String t) -> { 
    return Integer.parseInt(t);
}

 

 

β‘’ μœ„ κ΅¬μ‘°λ§ŒμœΌλ‘œλ„ λžŒλ‹€ ν‘œν˜„μ‹μ΄μ§€λ§Œ, μ’€ 더 κ°„κ²°ν•˜κ²Œ λ‚˜νƒ€λ‚΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.

    • Type μžλ£Œν˜•μ„ μ œκ±°ν•©λ‹ˆλ‹€.

     return 문도 μ œκ±°ν•©λ‹ˆλ‹€.

     ν•„μš”μ—†λŠ” μ€‘κ΄„ν˜Έλ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

Function<String, Integer> toInt = t -> Integer.pasreInt(t);

 

 

β‘£ μœ„ λžŒλ‹€μ‹μ„ λ©”μ†Œλ“œ μ°Έμ‘°λ₯Ό μ‚¬μš©ν•˜λ©΄ μ΅œμ’…μ μœΌλ‘œ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

Function<String, Integer> toInt = Integer::parseInt;

 

 

 

 

  • Consumer<T>

μœ„ 사진은 Consumer<T> 의 λ‚΄λΆ€ μ½”λ“œμ€‘ 일뢀 μž…λ‹ˆλ‹€.

​

μœ„ μΈν„°νŽ˜μ΄μŠ€μ—λŠ” λ‹€μŒκ³Ό 같은 좔상 λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

void accept(T t); // μ „λ‹¬λœ 인자 기반으둜 'λ°˜ν™˜' μ΄μ™Έμ˜ λ‹€λ₯Έ κ²°κ³Όλ₯Ό 보일 λ•Œ

Consumer μ†ŒλΉ„ν•œλ‹€ λΌλŠ” λ‹¨μ–΄λ§Œ 봐도 μœ μΆ”ν•  수 μžˆλ“―μ΄, μΈμžλŠ” μ „λ‹¬λ°›μ§€λ§Œ λ°˜ν™˜μ€ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

 

βœ” Consumer 예제

package other;

import java.util.function.Consumer;

public class FunctionalInterfaceExamples {

    public static void main(String[] args) {

        Consumer<String> print = new Consumer<String>() {
        
            @Override
            public void accept(String t) {
                System.out.println(t);
            }
        };

        //Consumer<String> print = System.out::println;
        print.accept("Hello World");
    }
}

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μΈ Consumer<T>을 μ‚¬μš©ν•΄ λ‚΄λΆ€μ˜ accept() λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•œ μ½”λ“œμž…λ‹ˆλ‹€.

​(λžŒλ‹€ ν‘œνŽΈμ‹μ€ 주석 처리λ₯Ό 해놓은 뢀뢄이며, λžŒλ‹€ λ°©μ‹μœΌλ‘œμ˜ 과정은 μƒλž΅ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€!)

 

 

 

 

  • Predicate<T>

μœ„ 사진은 Predicate<T> 의 λ‚΄λΆ€ μ½”λ“œμ€‘ 일뢀 μž…λ‹ˆλ‹€.

​

μœ„ μΈν„°νŽ˜μ΄μŠ€μ—λŠ” λ‹€μŒκ³Ό 같은 좔상 λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

boolean test(T t); // μ „λ‹¬λœ 인자λ₯Ό λŒ€μƒμœΌλ‘œ True, False λ₯Ό νŒλ‹¨ν•  λ•Œ

β€‹λ”°λΌμ„œ Predicate<T> μΈν„°νŽ˜μ΄μŠ€λŠ” μ „λ‹¬λœ 인자λ₯Ό νŒλ‹¨ν•˜μ—¬ true λ˜λŠ” falseλ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•˜λŠ” μƒν™©μ—μ„œ μœ μš©ν•©λ‹ˆλ‹€.

 

 

βœ” Predicate 예제

package other;

import java.util.function.Predicate;

public class FunctionalInterfaceExamples {

    public static void main(String[] args) {

        Predicate<Integer> isPositive = i -> i > 0;

        System.out.println(isPositive.test(-1));
        System.out.println(isPositive.test(0));
        System.out.println(isPositive.test(1));
    }
}

 

 

package other;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class FunctionalInterfaceExamples {

    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5);
        List<Integer> positiveNumbers = new ArrayList<>();

        /* μ–‘μˆ˜λ§Œ μ €μž₯ */
        for (Integer num : numbers) {
            if (num > 0) {
                positiveNumbers.add(num);
            }
        }

        System.out.println("Positive Integers: " + positiveNumbers);

        Predicate<Integer> lessThan3 = i -> i < 3;
        List<Integer> numbersLessThan3 = new ArrayList<>();

        /* μ–‘μˆ˜λ§Œ μ €μž₯ */
        for (Integer num : numbers) {
            if (lessThan3.test(num)) {
                numbersLessThan3.add(num);
            }
        }
        System.out.println("numbersLessThan3: " + numbersLessThan3);
    }
}

μœ„ μ½”λ“œλŠ” Listλ₯Ό μƒμ„±ν•˜κ³ , for문을 μˆœνšŒν•˜λ©° 쑰건문을 톡해 ν•„ν„°λ§ν•˜λŠ” λ™μΌν•œ μ½”λ“œκ°€ μ€‘λ³΅λ˜λŠ”

보일러 ν”Œλ ˆμ΄νŠΈ μ½”λ“œκ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

 

ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ„œ λΉΌλ‚Έ λ’€ 쀑볡 μ½”λ“œλ₯Ό μ œκ±°ν•΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

package other;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class FunctionalInterfaceExamples {

    private static <T> List<T> filter(List<T> list, Predicate<T> filters) {
        List<T> result = new ArrayList<>();
        for (T input : list) {
            if (filters.test(input)) {    // Predicate의 쑰건에 따라 λΆ„λ₯˜
                result.add(input);
            }
        }
        return result;
    }

    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5);

        Predicate<Integer> isPositive = i -> i > 0;

        List<Integer> positiveNumbers = new ArrayList<>();

        /* μ–‘μˆ˜λ§Œ μ €μž₯ */
        for (Integer num : numbers) {
            if (num > 0) {
                positiveNumbers.add(num);
            }
        }

        System.out.println("Positive Integers: " + positiveNumbers);

        Predicate<Integer> lessThan3 = i -> i < 3;
        List<Integer> numbersLessThan3 = new ArrayList<>();

        for (Integer num : numbers) {
            if (lessThan3.test(num)) {
                numbersLessThan3.add(num);
            }
        }

        System.out.println("numbersLessThan3: " + numbersLessThan3);
        System.out.println("Positive Integers: " + filter(numbers, isPositive));
        //System.out.println("Positive Integers: " + filter(numbers, i -> i > 0));
        System.out.println("numbersLessThan3: " + filter(numbers, lessThan3));
    }

}

 

 

List 와 Predicate λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ” μ œλ„€λ¦­ λ©”μ„œλ“œ filter() λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

​

filter() ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜μ˜ List μ›μ†Œλ“€μ— λŒ€ν•΄ λ°˜λ³΅λ¬Έμ„ 톡해 Predicate<T> μΈν„°νŽ˜μ΄μŠ€μ˜ test λ©”μ„œλ“œλ₯Ό 톡해 true인 경우 리턴할 List인 result 에 μ €μž₯ν•©λ‹ˆλ‹€. 말이 κΈΈμ–΄μ‘ŒλŠ”λ°μš”, μš”μ•½ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

​

List , Predicateλ₯Ό 인자둜 λ°›κ³ , List의 μ›μ†Œλ“€μ΄ νŠΉμ • 쑰건을 λ§Œμ‘±ν•  경우(test) λ‹€λ₯Έ 리슀트(result)에 μ €μž₯ν•©λ‹ˆλ‹€.

 

 

 

λ§ˆμ§€λ§‰μœΌλ‘œ Predicate<T> μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 ν™€μˆ˜, 짝수의 합을 κ΅¬ν•˜λŠ” 예제λ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€.

package other;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class PredicateExample {

    public static int filterSum(Predicate<Integer> filter, List<Integer> list) {
        int sum = 0;
        for (Integer num : list) {
            if (filter.test(num)) {
                sum += num;
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        int sum;
        sum = filterSum(i -> i % 2 == 0, list);
        System.out.println("짝수 ν•©: " + sum);

        sum = filterSum(i -> i % 2 == 1, list);
        System.out.println("ν™€μˆ˜ ν•©: " + sum);
    }

}

 

 

 

 

  • Supplier<T>

μœ„ 사진은 Supplier<T> 의 λ‚΄λΆ€ μ½”λ“œ μž…λ‹ˆλ‹€.

​

μΈν„°νŽ˜μ΄μŠ€λŠ” λ‹€μŒκ³Ό 같은 μΆ”μƒλ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

T get(); // λ§€κ°œλ³€μˆ˜κ°€ μ—†κ³ , λ‹¨μˆœνžˆ 무엇인가λ₯Ό λ°˜ν™˜ν•  λ•Œ

λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ“€μ˜ μΆ”μƒλ©”μ„œλ“œλŠ” λͺ¨λ‘ λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•˜λŠ”λ°,

Supplier<T> λŠ” νŠΉμ΄ν•˜κ²Œ λ§€κ°œλ³€μˆ˜λ₯Ό 받지 μ•Šκ³  λ‹¨μˆœνžˆ 무엇인가λ₯Ό λ°˜ν™˜ν•˜λŠ” μΆ”μƒλ©”μ„œλ“œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

​

package other;

import java.util.function.Supplier;

public class SupplierExample {

    public static void main(String[] args) {
        Supplier<String> helloSupplier = () -> "Hello ";

        System.out.println(helloSupplier.get() + "World");
    }
}

μœ„ μ½”λ“œμ—μ„œ Supplier<T>의 μ œλ„€λ¦­ νƒ€μž…μ€ String μ΄λ―€λ‘œ, helloSupplier.get() 을 톡해 "Hello " λ₯Ό λ°›μ•„μ˜¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

​

​

Supplier<T> μΈν„°νŽ˜μ΄μŠ€λŠ” 좔상 λ©”μ„œλ“œ get()을 톡해 Lazy Evaluation 이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

Lazy Evaluation
직역은 "게으λ₯Έ μ—°μ‚°"으둜, λΆˆν•„μš”ν•œ 연산을 ν”Όν•˜κΈ° μœ„ν•΄ 연산을 μ§€μ—°μ‹œν‚€λŠ” 것을 λ§ν•©λ‹ˆλ‹€.​
즉, λΆˆν•„μš”ν•œ 연산을 ν”Όν•œλ‹€ λŠ” μ˜λ―Έμž…λ‹ˆλ‹€.

 

Lazy Evaluation을 톡해 효율적인 λ™μž‘μ„ μ΄λŒμ–΄ λ‚Ό 수 μžˆλŠ” μ½”λ“œλ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

getVeryExpensiveValue() λ©”μ„œλ“œλŠ” 3μ΄ˆκ°„ sleep ν›„ "JuHyun" 을 λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜μ΄κ³ ,

printIfValidIndex(int number, String value) λ©”μ„œλ“œλŠ” 쑰건에따라 좜λ ₯을 λ‹¬λ¦¬ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

​

μœ„ ν•¨μˆ˜μ—μ„œ number의 값에 관계 없이 λ©”μ„œλ“œκ°€ 총 3번 호좜이 되기 λ•Œλ¬Έμ— 9μ΄ˆκ°€ κ²½κ³Όν•˜κ²Œ λ©λ‹ˆλ‹€.

 

이제 μœ„ μ½”λ“œλ₯Ό Supplier<T> μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 Lazy Evaluation λΆˆν•„μš”ν•œ 연산을 쀄여보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

μœ„μ˜ κ²½μš°μ—λŠ” printInfValidIndex() λ©”μ„œλ“œμ˜ λ§€κ°œλ³€μˆ˜λ‘œ λ©”μ„œλ“œμ˜ λ°˜ν™˜κ°’μ΄ μ•„λ‹Œ, ν•¨μˆ˜κ°€ μ „λ‹¬λ˜μ—ˆκΈ° λ•Œλ¬Έμ— μ‹€μ œμ μœΌλ‘œ valueSupplier.get() 을 ν˜ΈμΆœν•  λ•Œλ§Œ getVeryExpensiveValue() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ λ©λ‹ˆλ‹€.

​

μœ„ μ½”λ“œμ˜ κ²°κ³Όλ₯Ό 보면 μ‹€μ œμ μœΌλ‘œ λΆˆν•„μš”ν•œ 연산을 μ œκ±°ν•˜κ³ , κ²°κ³Όκ°€ 3초둜 λ‚˜μ˜€λŠ”κ²ƒμ„ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

​

 

μ΄μƒμœΌλ‘œ Java8에 μΆ”κ°€λœ λŒ€ν‘œμ μΈ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

 

​

 

 

βœ” References

https://codechacha.com/ko/java8-functional-interface/

​

https://velog.io/@litien/Modern-Java-Java-8-%ED%95%A8%EC%88%98%ED%98%95-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

​

https://youtu.be/mu9XfJofm8U

​

http://m.yes24.com/goods/detail/43755519

​

https://docs.oracle.com/javase/8/docs/api/

 

 

 

λ°˜μ‘ν˜•

λŒ“κΈ€