BackEnd🌱/Java

Java의 κΈ°λ³Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

dkswnkk 2023. 3. 20. 20:16

μ„œλ‘ 

사내 μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ‹€κ°€ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€, κ·Έμ€‘μ—μ„œλ„ BiFunction<T, U, R>을 μ‚¬μš©ν•œ λ‘œμ§μ„ 자주 λ³Ό 수 μžˆμ—ˆλŠ”λ°, μ‹€μ œλ‘œ λ³΄λ‹ˆ μƒμ†Œν•˜κΈ°λ„ ν•˜κ³ , 저도 λ‘œμ§μ— ν•œλ²ˆ 녹여보고 μ‹Άμ–΄μ„œ 이번 κΈ°νšŒμ— 정리λ₯Ό 해보렀고 ν•©λ‹ˆλ‹€.
 

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μ’…λ₯˜

Java의 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” JAVA 8λΆ€ν„° λ„μž…λœ κΈ°λŠ₯으둜, ν•˜λ‚˜μ˜ 좔상 λ©”μ„œλ“œλ§Œ κ°€μ§€λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μΈν„°νŽ˜μ΄μŠ€λ“€μ€ λžŒλ‹€ ν‘œν˜„μ‹μ΄λ‚˜ λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό 톡해 κ°„λ‹¨ν•˜κ²Œ ν‘œν˜„ν•  μˆ˜ 있으며, Javaμ—μ„œλŠ” java.util.function νŒ¨ν‚€μ§€λ₯Ό 톡해 미리 μ •μ˜λœ λ‹€μ–‘ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.
Javaμ—μ„œ 미리 μ •μ˜ν•΄ λ‘” μ£Όμš” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  1. Function<T, R>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ κ²°κ³Ό R을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 주둜 데이터 λ³€ν™˜ μž‘μ—…μ— μ‚¬μš©λœλ‹€.
    • R apply(T t)
  2. BiFunction<T, U, R>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ κ²°κ³Ό R을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
    • R apply(T t, U u)
  3. Consumer<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. λ°˜ν™˜κ°’μ€ μ—†μœΌλ©°, 주둜 데이터λ₯Ό μ†ŒλΉ„ν•˜λŠ” μž‘μ—…μ— μ‚¬μš©λœλ‹€.
    • void accept(T t)
  4. BiConsumer<T, U>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. λ°˜ν™˜ 값은 μ—†λ‹€.
    • void accept(T t, U u)
  5. Supplier<T>: μž…λ ₯ 인수 없이 κ²°κ³Ό Tλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 주둜 값을 μƒμ„±ν•˜κ±°λ‚˜ κ³΅κΈ‰ν•˜λŠ” μž‘μ—…μ— μ‚¬μš©λœλ‹€.
    • T get()
  6. Predicate<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ boolean 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 주둜 쑰건 검사에 μ‚¬μš©λœλ‹€.
    • boolean test(T t)
  7. BiPredicate<T, U>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ boolean 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
    • boolean test(T t, U u)
  8. UnaryOperator<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ λ™μΌν•œ μœ ν˜•μ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. Function<T, T>의 μ„œλΈŒ μΈν„°νŽ˜μ΄μŠ€μ΄λ©°, 주둜 단항 μ—°μ‚° μž‘μ—…μ— μ‚¬μš©λœλ‹€.
    • T apply(T t)
  9. BinaryOperator<T>: 두 개의 μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ λ™μΌν•œ μœ ν˜•μ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. BiFunction<T, T, T>의 μ„œλΈŒ μΈν„°νŽ˜μ΄μŠ€μ΄λ©°, 주둜 이항 μ—°μ‚° μž‘μ—…μ— μ‚¬μš©λœλ‹€.
    • T apply(T t1, T t2)
  10. 이 μ™Έμ˜ ν•¨μˆ˜λ“€

 

예제

⭐️ Function<T, R> : μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ κ²°κ³Ό R을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜, 주둜 데이터 λ³€ν™˜ μž‘μ—…μ— μ‚¬μš©

import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        Function<String, Integer> strLength = str -> str.length();

        System.out.println("Length of 'Hello': " + strLength.apply("Hello")); // 좜λ ₯: Length of 'Hello': 5
    }
}

 

⭐️ BiFunction<T, U, R>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ κ²°κ³Ό R을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜

import java.util.function.BiFunction;

public class Main {
    public static void main(String[] args) {
        BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;

        System.out.println("10 + 20 = " + add.apply(10, 20)); // 좜λ ₯: 10 + 20 = 30
    }
}

 

⭐️ Consumer<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜, λ°˜ν™˜κ°’μ€ μ—†μœΌλ©°, 주둜 데이터λ₯Ό μ†ŒλΉ„ν•˜λŠ” μž‘μ—…μ— μ‚¬μš©

import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase());

        printUpperCase.accept("hello world"); // 좜λ ₯: HELLO WORLD
    }
}

 

⭐️ BiConsumer<T, U>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜, λ°˜ν™˜ 값은 μ—†μŒ

import java.util.function.BiConsumer;

public class Main {
    public static void main(String[] args) {
        BiConsumer<String, Integer> printNTimes = (str, n) -> {
            for (int i = 0; i < n; i++) {
                System.out.println(str);
            }
        };

        printNTimes.accept("Hello", 3);
        // 좜λ ₯:
        // Hello
        // Hello
        // Hello
    }
}

 

⭐️ Supplier<T>: μž…λ ₯ 인수 없이 κ²°κ³Ό Tλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜, 주둜 값을 μƒμ„±ν•˜κ±°λ‚˜ κ³΅κΈ‰ν•˜λŠ” μž‘μ—…μ— μ‚¬μš©

import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Supplier<Double> randomSupplier = () -> Math.random();

        System.out.println("Random number: " + randomSupplier.get()); // 좜λ ₯: Random number: 0.123456789 (μ˜ˆμ‹œ)
    }
}

 

⭐️ Predicate<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ boolean 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜, 주둜 쑰건 검사에 μ‚¬μš©

import java.util.function.Predicate;

public class Main {
    public static void main(String[] args) {
        Predicate<Integer> isEven = num -> num % 2 == 0;

        System.out.println("10은 μ§μˆ˜μž…λ‹ˆκΉŒ? " + isEven.test(10)); // 좜λ ₯: 10은 μ§μˆ˜μž…λ‹ˆκΉŒ? true
        System.out.println("15은 μ§μˆ˜μž…λ‹ˆκΉŒ? " + isEven.test(15)); // 좜λ ₯: 15은 μ§μˆ˜μž…λ‹ˆκΉŒ? false
    }
}

 

⭐️ BiPredicate<T, U>: 두 개의 μž…λ ₯ 인수 T와 Uλ₯Ό λ°›μ•„ boolean 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜

import java.util.function.BiPredicate;

public class Main {
    public static void main(String[] args) {
        BiPredicate<Integer, Integer> areBothEven = (a, b) -> a % 2 == 0 && b % 2 == 0;

        System.out.println("10κ³Ό 20은 λͺ¨λ‘ μ§μˆ˜μΈκ°€? " + areBothEven.test(10, 20)); // 좜λ ₯: 10κ³Ό 20은 λͺ¨λ‘ μ§μˆ˜μΈκ°€? true
        System.out.println("10κ³Ό 15은 λͺ¨λ‘ μ§μˆ˜μΈκ°€? " + areBothEven.test(10, 15)); // 좜λ ₯: 10κ³Ό 15은 λͺ¨λ‘ μ§μˆ˜μΈκ°€? false
    }
}

 

⭐️ UnaryOperator<T>: μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ λ™μΌν•œ μœ ν˜•μ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜, 주둜 단항 μ—°μ‚° μž‘μ—…μ— μ‚¬μš©

import java.util.function.UnaryOperator;

public class Main {
    public static void main(String[] args) {
        UnaryOperator<Integer> square = num -> num * num;

        System.out.println("5의 제곱: " + square.apply(5)); // 좜λ ₯: 5의 제곱: 25
    }
}

 

⭐️ BinaryOperator<T>: 두 개의 μž…λ ₯ 인수 Tλ₯Ό λ°›μ•„ λ™μΌν•œ μœ ν˜•μ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜, 주둜 이항 μ—°μ‚° μž‘μ—…μ— μ‚¬μš©

import java.util.function.BinaryOperator;

public class Main {
    public static void main(String[] args) {
        BinaryOperator<Integer> multiply = (a, b) -> a * b;

        System.out.println("5 * 10 = " + multiply.apply(5, 10)); // 좜λ ₯: 5 * 10 = 50
    }
}

 

 

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ μž₯점

  • κ°„κ²°ν•œ μ½”λ“œ: λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜λ©΄ μ½”λ“œλ₯Ό 더 κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•  수 있으며, μ΄λŠ” μ½”λ“œμ˜ 가독성과 μœ μ§€ λ³΄μˆ˜μ„±μ„ 높인닀.
  • 높은 λͺ¨λ“ˆμ„±: ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ 순수 ν•¨μˆ˜μ™€ 높은 λͺ¨λ“ˆμ„±μ„ 지ν–₯ν•œλ‹€. 이λ₯Ό 톡해 μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•˜κΈ° μ‰¬μ›Œμ§€λ©°, ν…ŒμŠ€νŠΈμ™€ 디버깅이 μš©μ΄ν•΄μ§„λ‹€.
  • λΆˆλ³€μ„±: ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μƒνƒœ 변경을 μ΅œμ†Œν™”ν•˜λ©° λΆˆλ³€ 데이터 ꡬ쑰λ₯Ό μ‚¬μš©ν•œλ‹€. 이둜 인해 μ•ˆμ „μ„±μ΄ 높아지며, 버그 λ°œμƒ κ°€λŠ₯성이 쀄어든닀.
  • κ³ μ°¨ ν•¨μˆ˜ μ‚¬μš©: κ³ μ°¨ ν•¨μˆ˜λŠ” ν•¨μˆ˜λ₯Ό 인자둜 λ°›κ±°λ‚˜ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄κΈ°μ—, κ³ μ°¨ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ‘°ν•©ν•˜κ±°λ‚˜ μΆ”μƒν™”ν•˜μ—¬ κ°•λ ₯ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•  수 μžˆλ‹€.
  • μžμ—°μŠ€λŸ¬μš΄ 병렬 처리: ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ λΆ€μˆ˜ 효과(Side Effect)κ°€ μ—†λŠ” 순수 ν•¨μˆ˜λ₯Ό μ„ ν˜Έν•˜λ―€λ‘œ, λ™μ‹œμ„±κ³Ό 병렬 μ²˜λ¦¬μ— μ ν•©ν•˜λ‹€. 이λ₯Ό 톡해 λ©€ν‹°μ½”μ–΄ μ‹œμŠ€ν…œμ—μ„œ μ„±λŠ₯ ν–₯상을 얻을 수 μžˆλ‹€.
  • 지연 평가: ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” 지연 평가(Lazy Evaluation)λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. 이λ₯Ό 톡해 λΆˆν•„μš”ν•œ 계산을 ν”Όν•˜κ³ , μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€.
  • μ»¬λ ‰μ…˜ 처리의 νš¨μœ¨μ„±: ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μ»¬λ ‰μ…˜ μ²˜λ¦¬μ— λŒ€ν•œ κ°•λ ₯ν•œ 도ꡬλ₯Ό μ œκ³΅ν•œλ‹€. 슀트림 APIλ₯Ό μ‚¬μš©ν•˜λ©΄ μ»¬λ ‰μ…˜μ„ μ‰½κ²Œ μ‘°μž‘ν•˜κ³  λ°˜ν™˜ν•  수 μžˆλ‹€.

 

 

λ²ˆμ™Έ

μΆ”κ°€λ‘œ μ œκ°€ μ•Œκ³ μ‹Άμ—ˆλ˜ BiFunction에 λŒ€ν•΄μ„œ 더 μžμ„Ένžˆ μ •λ¦¬ν•˜κ² μŠ΅λ‹ˆλ‹€.
λ¨Όμ € BiFunction μΈν„°νŽ˜μ΄μŠ€μ˜ μ •μ˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);
}

μ—¬κΈ°μ„œ T, U, R은  μ œλ„€λ¦­ νƒ€μž…μ΄λ©°, 각각 두 개의 μž…λ ₯ μΈμžμ™€ λ°˜ν™˜ 값에 ν•΄λ‹Ήν•˜λŠ” νƒ€μž…μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
BiFunction μΈν„°νŽ˜μ΄μŠ€μ—λŠ” λ‹€μŒ λ©”μ„œλ“œλ“€μ΄ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

  1. apply(T t, U u): 두 개의 인자λ₯Ό λ°›μ•„μ„œ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œλ‹€. 이 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ—¬ μ‹€μ œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λœλ‹€.
  2. andThen(Function<? super R, ? extents V> after): 이 λ©”μ„œλ“œλŠ” ν˜„μž¬μ˜ BiFunction μΈμŠ€ν„΄μŠ€μ™€ λ‹€λ₯Έ Function μΈμŠ€ν„΄μŠ€λ₯Ό μ—°κ²°ν•˜λ©°, ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ κ²°κ³Όλ₯Ό λ‹€λ₯Έ ν•¨μˆ˜μ˜ μž…λ ₯으둜 μ‚¬μš©ν•œλ‹€. λ”°λΌμ„œ μ΅œμ’…μ μœΌλ‘œ μƒˆλ‘œμš΄ BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.

μ˜ˆμ œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

import java.util.function.BiFunction;

public class Main {
    public static void main(String[] args) {
        // BiFunction μΈμŠ€ν„΄μŠ€ 생성
        BiFunction<Integer, Integer, Integer> adder = (a, b) -> a + b;

        // apply λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 숫자λ₯Ό 더함
        int result = adder.apply(5, 3);
        System.out.println("5 + 3 = " + result);

        // andThen λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 ν•¨μˆ˜λ₯Ό μ—°κ²°
        BiFunction<Integer, Integer, Integer> multiplier = (a, b) -> a * b;
        Function<Integer, String> toString = num -> "κ²°κ³Ό: " + num;

        BiFunction<Integer, Integer, String> combined = adder.andThen(toString);
        String combinedResult = combined.apply(5, 3);
        System.out.println(combinedResult);
    }
}

좜λ ₯ κ²°κ³Ό
5 + 3 = 8
κ²°κ³Ό: 8

μœ„ μ½”λ“œλŠ” 두 개의 BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , apply λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 숫자λ₯Ό λ”ν•œ λ‹€μŒ, andThen λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ κ²°κ³Όλ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜λŠ” ν•¨μˆ˜μ™€ μ—°κ²°ν•©λ‹ˆλ‹€.

import java.util.function.BiFunction;
import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        // λ¬Έμžμ—΄ κ²°ν•© BiFunction μΈμŠ€ν„΄μŠ€ 생성
        BiFunction<String, String, String> concat = (a, b) -> a + b;

        // apply λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 λ¬Έμžμ—΄μ„ κ²°ν•©
        String result = concat.apply("Hello, ", "World!");
        System.out.println("κ²°κ³Ό: " + result);

        // andThen λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λŒ€λ¬Έμž λ³€ν™˜ ν•¨μˆ˜λ₯Ό μ—°κ²°
        Function<String, String> toUpperCase = String::toUpperCase;
        BiFunction<String, String, String> combined = concat.andThen(toUpperCase);

        // μ—°κ²°λœ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄ κ²°ν•© 및 λŒ€λ¬Έμž λ³€ν™˜ μˆ˜ν–‰
        String combinedResult = combined.apply("hello, ", "world!");
        System.out.println(combinedResult);
    }
}

좜λ ₯ κ²°κ³Ό
κ²°κ³Ό: Hello, World!
HELLO, WORLD!

μœ„ μ½”λ“œλŠ” λ¬Έμžμ—΄ 결합을 μˆ˜ν–‰ν•˜λŠ” BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œ λ‹€μŒ, apply λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 λ¬Έμžμ—΄μ„ κ²°ν•©ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ andThen λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λŒ€λ¬Έμž λ³€ν™˜ ν•¨μˆ˜λ₯Ό μ—°κ²°ν•˜κ³ , μ—°κ²°λœ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄ κ²°ν•©κ³Ό λŒ€λ¬Έμž λ³€ν™˜μ„ λ™μ‹œμ— μˆ˜ν–‰ν•©λ‹ˆλ‹€.

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

public class Main {
    public static void main(String[] args) {
        // Map 생성 및 데이터 μ‚½μž…
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 10);
        map.put("B", 20);
        map.put("C", 30);

        // BiFunction μΈμŠ€ν„΄μŠ€ 생성
        BiFunction<Map<String, Integer>, String[], Integer> sumValues = (m, keys) -> {
            int sum = 0;
            for (String key : keys) {
                sum += m.getOrDefault(key, 0);
            }
            return sum;
        };

        // 두 킀에 λŒ€ν•œ κ°’μ˜ 합계λ₯Ό λ°˜ν™˜
        String[] keys = {"A", "B"};
        int result = sumValues.apply(map, keys);
        System.out.println("ν‚€ A와 ν‚€ B의 κ°’μ˜ 합계: " + result);
    }
}

좜λ ₯ κ²°κ³Ό
ν‚€ A와 ν‚€ B의 κ°’μ˜ 합계: 30

μœ„ μ½”λ“œλŠ” Map에 데이터λ₯Ό μ‚½μž…ν•œ ν›„, 두 킀에 λŒ€ν•œ κ°’μ˜ 합계λ₯Ό λ°˜ν™˜ν•˜λŠ” BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. apply λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ Mapκ³Ό ν‚€ 배열을 μ „λ‹¬ν•˜λ©΄, ν•¨μˆ˜λŠ” ν‚€ 배열에 ν•΄λ‹Ήν•˜λŠ” κ°’λ“€μ˜ 합계λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

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

public class Main {
    public static void main(String[] args) {
        // 두 개의 리슀트 생성
        List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3));
        List<Integer> list2 = new ArrayList<>(Arrays.asList(4, 5, 6));

        // BiFunction μΈμŠ€ν„΄μŠ€ 생성
        BiFunction<List<Integer>, List<Integer>, List<Integer>> addLists = (l1, l2) -> {
            List<Integer> result = new ArrayList<>();
            int size = Math.min(l1.size(), l2.size());
            for (int i = 0; i < size; i++) {
                result.add(l1.get(i) + l2.get(i));
            }
            return result;
        };

        // 두 λ¦¬μŠ€νŠΈμ—μ„œ λ™μΌν•œ 인덱슀의 μš”μ†Œλ“€μ„ 더함
        List<Integer> sumList = addLists.apply(list1, list2);
        System.out.println("두 리슀트의 μš”μ†Œλ³„ 합계: " + sumList);
    }
}

좜λ ₯ κ²°κ³Ό
두 리슀트의 μš”μ†Œλ³„ 합계: [5, 7, 9]

μœ„ μ½”λ“œλŠ” 두 개의 μ •μˆ˜ 리슀트λ₯Ό μƒμ„±ν•œ ν›„, λ™μΌν•œ 인덱슀의 μš”μ†Œλ“€μ„ λ”ν•˜λŠ” BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. apply λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 리슀트λ₯Ό μ „λ‹¬ν•˜λ©΄, ν•¨μˆ˜λŠ” 각 μΈλ±μŠ€λ³„ 합계λ₯Ό 가진 μƒˆλ‘œμš΄ 리슀트λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
λ˜ν•œ Javaμ—μ„œ μ œκ³΅ν•˜λŠ” λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ™€ μ‘°ν•©ν•˜μ—¬ 더 λ³΅μž‘ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, BiFunctionκ³Ό Function μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ λ‹€μ–‘ν•œ μž…λ ₯ 및 좜λ ₯ μœ ν˜•μ„ μ²˜λ¦¬ν•˜λŠ” νŠΉμ • μž‘μ—…μ„ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import java.util.function.BiFunction;
import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        // BiFunction μΈμŠ€ν„΄μŠ€ 생성
        BiFunction<String, Integer, String> repeat = (str, count) -> {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < count; i++) {
                sb.append(str);
            }
            return sb.toString();
        };

        // Function μΈμŠ€ν„΄μŠ€ 생성
        Function<String, Integer> countVowels = str -> {
            int count = 0;
            String vowels = "AEIOUaeiou";
            for (char c : str.toCharArray()) {
                if (vowels.indexOf(c) != -1) {
                    count++;
                }
            }
            return count;
        };

        // λ¬Έμžμ—΄ 반볡 및 λͺ¨μŒ 개수 계산
        String repeatedStr = repeat.apply("Hello", 3);
        int vowelCount = countVowels.apply(repeatedStr);

        System.out.println("반볡된 λ¬Έμžμ—΄: " + repeatedStr);
        System.out.println("λͺ¨μŒ 개수: " + vowelCount);
    }
}

좜λ ₯ κ²°κ³Ό
반볡된 λ¬Έμžμ—΄: HelloHelloHello
λͺ¨μŒ 개수: 6

μœ„ μ½”λ“œμ—μ„œλŠ” repeatλΌλŠ” BiFunction μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ λ¬Έμžμ—΄μ„ 주어진 횟수만큼 λ°˜λ³΅ν•˜κ³ , countVowelsλΌλŠ” Function μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ λ¬Έμžμ—΄μ—μ„œ λͺ¨μŒ 개수λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. κ·Έ ν›„, 두 ν•¨μˆ˜ν˜• μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ λ¬Έμžμ—΄μ—μ„œ λͺ¨μŒ 개수λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μ΅œμ’…μ μœΌλ‘œ 두 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄μ„ λ°˜λ³΅ν•œ ν›„ λͺ¨μŒ 개수λ₯Ό 계산할 수 μžˆμŠ΅λ‹ˆλ‹€.
이처럼 BiFunction을 λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ™€ ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ μž‘μ—…μ„ μ‘°ν•©ν•˜κ³ , μ½”λ“œμ˜ 가독성과 μœ μ—°μ„±μ„ ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ˜ 이점을 적극 ν™œμš©ν•˜μ—¬ μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±, ν…ŒμŠ€νŠΈ μš©μ΄μ„±, μœ μ§€ 관리성을 높일 수 μžˆκΈ°μ— 잘 μˆ™μ§€ν•΄μ„œ μ‚¬μš©ν–ˆμœΌλ©΄ μ’‹κ² μŠ΅λ‹ˆλ‹€.