π 1. Functional Interface(ν¨μν μΈν°νμ΄μ€)λ?
- λ¨ νλμ μΆμ λ©μλλ§ κ°μ§λ μΈν°νμ΄μ€λ₯Ό λ§ν¨. (default, static λ©μλλ μΆκ°λ‘ μμ΄λ μκ΄x)
- μ΄ μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ λλ€μ(Lambda Expression)μ΄λ λ©μλ μ°Έμ‘°(Method Reference)λ‘ κ΅¬ν κ°λ₯.
- μλ° 8λΆν° λμ
λ¨.
π‘ μ¦, “νλμ κΈ°λ₯μ νννλ μΈν°νμ΄μ€”λΌκ³ μκ°νλ©΄ νΈν¨.
μμ
// *@FunctionalInterface = λ¨ νλμ μΆμ λ©μλλ§ κ°μ§λλ‘ κ°μ νλ μ΄λ
Έν
μ΄μ
@FunctionalInterface
public interface MyFunctionalInterface {
void doSomething(); // λ¨ νλμ μΆμ λ©μλ
}
// λλ€μμΌλ‘ ꡬν κ°λ₯:
MyFunctionalInterface f = () -> System.out.println("Hello, Functional Interface!");
f.doSomething(); // μΆλ ₯: Hello, Functional Interface!
π 2. μλ°μμ μ 곡νλ λν Functional Interface
| μΈν°νμ΄μ€ | λ©μλ | μ©λ | μμ |
| Supplier | T get() | κ° κ³΅κΈ, μ§μ° μμ±, κΈ°λ³Έκ° | Supplier<String> s = () -> "Hello"; s.get(); // "Hello" |
| Consumer | void accept(T t) | μ λ ₯κ° μλΉ, μ²λ¦¬λ§ νκ³ λ°ν μμ | Consumer<String> c = s -> System.out.println(s); c.accept("Hi"); |
| Function<T,R> | R apply(T t) | μ λ ₯κ° λ³ν, λ§€ν, κ³μ° | Function<Integer,String> f = n -> "Number: "+n; f.apply(5); // "Number: 5" |
| Predicate | boolean test(T t) | 쑰건 κ²μ¬, νν°λ§ | Predicate<String> p = s -> s.length()>3; p.test("Hi"); // false |
π‘ μΆκ° ν¬μΈνΈ
- Supplier → Stream.generate(), κΈ°λ³Έκ°, λμ λ±
- Consumer → Stream.forEach(), κ° μ²λ¦¬λ§
- Function → Stream.map(), κ° λ³ν
- Predicate → Stream.filter(), 쑰건 κ²μ¬
π3. μ¬μ© μ΄μ
"κ·Έλ₯ λ©μλ μ§μ μ°κΈ°"λ λΉκ΅νμ λ λκ° μ’μκΉ?
π 곡ν΅μ μΌλ‘: λ¨μ μ€νλ³΄λ¨ μ¬μ¬μ©μ± + μ‘°ν©μ± + μ€νΈλ¦Ό API νμ©μ± λλ¬Έμ μ μ©νλ€!!
- Consumer → "μ€ν λμμ λκ²¨μ€ μ μλ€"
- Function → "λ³ν λ‘μ§μ λ 립μμΌ μ¬μ¬μ©/μ‘°ν©ν μ μλ€"
- Predicate → "쑰건μμ κ°μ²΄νν΄μ νν°λ§κ³Ό μ‘°ν©μ κ°λ ₯νλ€"
- Supplier → "κ°μ μμ±νλ μ±
μμ λΆλ¦¬ν μ μλ€"
β 3-1. Supplier μ¬μ© μ΄μ
Supplier<Double> randomSupplier = () -> Math.random();
System.out.println(randomSupplier.get()); // 0~1 μ¬μ΄ λμ
β κ·Έλ₯ Math.random() νΈμΆνλ©΄ λλλ° μ Supplier?
1οΈβ£ μ§μ° μ€ν → get() νΈμΆν λλ§ μ€νλ¨ (Lazy Evaluation). λΆνμν μμ λλΉλ₯Ό μ€μ΄κ³ ν¨μ¨μ μΌλ‘ μ€ν.
2οΈβ£ μ¬μ¬μ©μ± → κ° μμ± λ‘μ§μ λ³μλ‘ μ μ₯ν΄μ μ¬λ¬ κ³³μμ νμ© κ°λ₯.
3οΈβ£ μ λ΅ κ΅μ²΄ μ©μ΄ → randomSupplier = () -> new Random().nextDouble();→ ꡬν체 κ΅μ²΄ κ°λ₯, νΈμΆ μ½λλ κ·Έλλ‘ randomSupplier.get() μ¬μ©
4οΈβ£ μ€νΈλ¦Ό/ν
μ€νΈμμ μ μ© → Stream.generate(randomSupplier) κ°λ₯(무νμ€νΈλ¦Ό, .limit(N)μΌλ‘ μ ν), ν
μ€νΈ μ κ³ μ κ° μ£Όμ
κ°λ₯.
β‘οΈ μ¦, "μ¦μ μ€ν"μ΄ μλλΌ "κ°μ 곡κΈνλ λμμ κ°μ²΄νν΄μ μ μ°νκ² μΈ μ μλ€" κ° μ₯μ .
β 3-2. Consumer μ¬μ© μ΄μ
Consumer<String> printer = s -> System.out.println("Hello, " + s);
printer.accept("Java"); // Hello, Java
β κ·Έλ₯ System.out.println("Hello, Java") μ°λ©΄ λλλ° μ Consumer?
1οΈβ£ μ¬μ¬μ©μ± → Consumerλ₯Ό λ³μλ‘ μ μ₯ν΄μ μ¬λ¬ κ΅°λ° λ겨 μΈ μ μμ.
2οΈβ£ μ‘°ν© κ°λ₯ → andThen κ°μ λ©μλ 체μ΄λ μ§μ → μ¬λ¬ Consumerλ₯Ό ν©μ³μ μ€ν κ°λ₯.
3οΈβ£ μ λ΅ κ΅μ²΄ μ©μ΄ → κ°μ λ©μλ λ‘μ§μ΄λΌλ μν©μ λ°λΌ λ€λ₯Έ Consumerλ₯Ό μ£Όμ
κ°λ₯ (DI, μ λ΅ ν¨ν΄μ²λΌ).
β‘οΈ μ¦, "νλ² μ€ν"λ³΄λ€ "λμμ λκΈ°κ³ , μ‘°ν©νκ³ , κ΅μ²΄ν μ μλ€" κ° μ₯μ .
β 3-3. Function<T, R> μ¬μ© μ΄μ
Function<Integer, String> intToStr = i -> "Number: " + i;
System.out.println(intToStr.apply(10)); // Number: 10
β κ·Έλ₯ ("Number: " + 10) ν΄λ λλλ° Functionμ μ°λ μ΄μ ?
1οΈβ£ λ§΅ν λ‘μ§μ λ³μν → λ³ν κ³Όμ μ κ°μ²΄μ²λΌ μ λ¬ν μ μμ.
2οΈβ£ μ€νΈλ¦Ό APIμμ κ°λ ₯ → map(Function) κ³Ό κ°μ΄ λ°μ΄ν° νλ¦μμ λ³νμ νμ©.
3οΈβ£ ν¨μ ν©μ± μ§μ → andThen, compose λ‘ μ¬λ¬ Functionμ ν©μ³μ νμ΄νλΌμΈ μ²λ¦¬ κ°λ₯.
β‘οΈ μ¦, "λ°μ΄ν° λ³ν λ‘μ§μ λ 립μμΌ μ¬μ¬μ© + μ€νΈλ¦Ό μ²λ¦¬μ μ΅μ ν".
β 3-4. Predicate μ¬μ© μ΄μ
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // true
β κ·Έλ₯ if (n % 2 == 0) νλ©΄ λλλ° μ Predicate?
1οΈβ£ 쑰건μ κ°μ²΄μ²λΌ μ λ¬ κ°λ₯ → λ©μλ νλΌλ―Έν°λ‘ "쑰건"μ λκ²¨μ€ μ μμ.
2οΈβ£ μ€νΈλ¦Ό νν°λ§μμ ν΅μ¬ → filter(Predicate) μ κ°μ΄ 쑰건μ νμ©.
3οΈβ£ 쑰건 μ‘°ν© κ°λ₯ → and, or, negate λ±μΌλ‘ μ¬λ¬ 쑰건μ μ μ°νκ² ν©μΉ μ μμ.
β‘οΈ μ¦, "쑰건μ μ½λλ‘ μ§μ μ°λ λμ , λ 립λ κ°μ²΄λ‘ λ€λ£¨λ©΄μ μ‘°ν©/μ λ¬ κ°λ₯".
π 4. μ°Έκ³ - Javaμμ μ 곡νλ Functional Interface μ 체
- μλ° 8 μ΄ν java.util.function ν¨ν€μ§μ μ½ 43κ° μ λκ° μμ (2~3μμ μ€λͺ ν λν4κ°λ§ μμλμ..π’)
- ν¬κ² μ λ ₯/μΆλ ₯/쑰건/μ‘°ν©/νΉννμΌλ‘ λλλ€.
- *Runnableκ³Ό Callableλ Functional Interfaceμ μΌμ’ μ΄λ€!!
1οΈβ£ μ λ ₯κ³Ό μΆλ ₯ κΈ°μ€
| νμ | μμ |
| λ§€κ°λ³μ X, λ¦¬ν΄ O | Supplier<T> |
| λ§€κ°λ³μ O, λ¦¬ν΄ X | Consumer<T>, BiConsumer<T,U> |
| λ§€κ°λ³μ O, λ¦¬ν΄ O | Function<T,R>, BiFunction<T,U,R> |
| λ§€κ°λ³μ O, λ¦¬ν΄ boolean | Predicate<T>, BiPredicate<T,U> |
2οΈβ£ νΉνν(Primitiveμ©)
μ±λ₯ μ΅μ ν μν΄ int, long, double λ²μ μ 곡
| νμ | μμ |
| int | IntSupplier, IntConsumer, IntFunction<R>, IntPredicate |
| long | LongSupplier, LongConsumer, LongFunction<R>, LongPredicate |
| double | DoubleSupplier, DoubleConsumer, DoubleFunction<R>, DoublePredicate |
3οΈβ£ μ‘°ν©μ©
κΈ°μ‘΄ Functional Interfaceλ₯Ό μ°κ²°νκ±°λ λ³νν λ μ¬μ©
| μμ | μ€λͺ |
| UnaryOperator<T> | Function<T,T>μ κ°μ, μκΈ° μμ μΌλ‘ λ§€ν |
| BinaryOperator<T> | BiFunction<T,T,T>μ κ°μ, λ κ°μΌλ‘ κ²°κ³Ό μμ± |
'Backend > JAVA' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| Streamingμ΄λ? (0) | 2025.12.18 |
|---|---|
| jsonνμΌ μ½κΈ° (0) | 2025.12.18 |
| [JAVA] Client IP, Device Type μΆμΆ (IP κΈ°λ° λ‘κ·ΈμΈ) (0) | 2025.12.18 |
| λλ DB INSERT μ΅μ ν (0) | 2025.11.29 |
| νμΌ μ λ‘λ, λ€μ΄λ‘λ (MultipartFile) (0) | 2025.11.08 |