๐Ÿ“– Functional Interface


ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

์ž๋ฐ” 8๋ถ€ํ„ฐ ์ž๋ฐ”๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜์—ˆ๋‹ค.

์ž๋ฐ”์—์„œ๋Š” ์ˆซ์ž, ๋ฌธ์ž ๊ฐ™์€ ์›์‹œ ํƒ€์ž…, ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ์ •์˜ํ•˜๋Š” ์ฐธ์กฐ ํƒ€์ž… ๊ฐ์ฒด๋“ค์ด
์ผ๊ธ‰ ๊ฐ์ฒด๊ฐ€ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ,
(ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋“ฑ์žฅํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š”) ํ•จ์ˆ˜์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ์ผ๊ธ‰ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค.

๋•๋ถ„์— ์˜ค๋Š˜ ๋œฏ์–ด ๋ณผ Functional Interface์˜ ๋“ฑ์žฅ์œผ๋กœ,
๊ฐ์ฒด ์•ˆ์—๋งŒ ์กด์žฌํ–ˆ๋˜ ํ•จ์ˆ˜(๋ฉ”์„œ๋“œ)๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ๋˜์—ˆ๋‹ค.

๐Ÿค” ์ผ๊ธ‰ ๊ฐ์ฒดโ€ฆ?
์–ด๋–ค ๊ฐœ์ฒด๊ฐ€ ๋‹ค์Œ 3๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋ผ๊ณ  ๋งํ•œ๋‹ค.

  • ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ณ€์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์•ˆ์— ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค.
  • ํ• ๋‹น์— ์‚ฌ์šฉ๋œ ์ด๋ฆ„๊ณผ ๊ด€๊ณ„์—†์ด ๊ณ ์œ ํ•œ ๊ตฌ๋ณ„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ํ•˜๊ธฐ

์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋”ฑ ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ํ•œ๋‹ค.
์ž๋ฐ”์˜ ๋žŒ๋‹ค์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋‹ค๋ค„์ง„๋‹ค.
ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋žŒ๋‹ค์‹๊ณผ ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์†Œ๋“œ๊ฐ€ 1:1๋กœ ์—ฐ๊ฒฐ๋˜๊ธฐ ์œ„ํ•ด,
์ถ”์ƒ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋‹จ ํ•˜๋‚˜๋ฟ์ธ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.
(static, defualt ๋ฉ”์„œ๋“œ๋Š” ์ œ์™ธ๋‹ค.)

์ž๋ฐ”์—์„œ๋Š” ์ด๋ฅผ @FunctionalInterface ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‚˜ํƒ€๋‚ธ๋‹ค.
์ฐธ๊ณ ๋กœ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ผ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ์—”ํ‹ฐํ‹ฐ๊ฐ€
๋‹จ์ผ ์ถ”์ƒ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–์ถ˜ ์ธํ„ฐํŽ˜์ด์Šค์ธ์ง€ ๊ฒ€์‚ฌํ•˜๋‹ˆ ๋ถ™์ด๋„๋ก ํ•˜์ž.

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

๋ฏธ๋ฆฌ ์ •์˜๋˜์–ด ์žˆ๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

java.util.function ํŒจํ‚ค์ง€

์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•œ๋‹ค๋ฉด, ๋งค๊ฐœ๋ณ€์ˆ˜๋‚˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ๋‹ฌ๋ผ๋„ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
๋•Œ๋ฌธ์— ์ž๋ฐ” ํŒจํ‚ค์ง€์—์„œ๋Š” ์ž์ฃผ ์“ฐ์ด๋Š” ํ˜•์‹์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ
๋ฏธ๋ฆฌ ์ •์˜ํ•ด ๋†“์•˜๋‹ค.
์‚ฌ์‹ค ๋งค๋ฒˆ ๋žŒ๋‹ค์‹์„ ์œ„ํ•ด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๊ท€์ฐฎ์€ ์ผ์ด๋‹ˆ
๊ฐ€๊ธ‰์  ์ด ํŒจํ‚ค์ง€์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ž!

ํ‘œ์ค€์œผ๋กœ ์ •์˜๋œ ๋Œ€ํ‘œ์  ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ทธ ์•ˆ์— ์žˆ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์ถ”์ƒ ๋ฉ”์„œ๋“œ
Predicate<T> boolean test(T t)
Supplier<T> T get()
Consumer<T> void accept(T t)
Funtion<T, R> R apply(T t)

Predicate<T>

๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… T, ๋ฐ˜ํ™˜ํƒ€์ž… Boolean

boolean test(T t); 
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 2๊ฐœ์ธ ๊ฒฝ์šฐ BiPredicate<T, U>

์ „๋‹ฌ๋œ ์ธ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ true, false๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

class PredicateDemo {
    public static int sum(Predicate<Integer> p, List<Integer> lst) {
        int s = 0;
        
        for(int n : lst) {
            if(p.test(n))
                s += n;
        }       
        
        return s;
    }
    
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 5, 7, 9, 11, 12);
    
        int s;
        s = sum(n -> n%2 == 0, list);
        System.out.println("์ง์ˆ˜ ํ•ฉ: " + s);

        s = sum(n -> n%2 != 0, list);
        System.out.println("ํ™€์ˆ˜ ํ•ฉ: " + s);

    }
}

sum(Predicate<Integer> p, List<Integer> lst)์—๋Š”
boolean test(Integer t) ๋ฉ”์†Œ๋“œ ์ •์˜์— ํ•ด๋‹นํ•˜๋Š” ๋žŒ๋‹ค์‹์„ ์ž‘์„ฑํ•ด์„œ ์ „๋‹ฌํ•ด์•ผํ•œ๋‹ค.

Supplier<T>

๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์Œ, ๋ฐ˜ํ™˜ ํƒ€์ž… T

T get();

๋‹จ์ˆœํžˆ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

class SupplierDemo {
    public static List<Integer> makeIntList(Supplier<Integer> s, int n) {
        List<Integer> list = new ArrayList<>();    
        for(int i = 0; i < n; i++)
            list.add(s.get());
        return list;
    }
    
    public static void main(String[] args) {
        Supplier<Integer> spr = () -> {
            Random rand = new Random();
            return rand.nextInt(50);
        };

        List<Integer> list = makeIntList(spr, 5);
        System.out.println(list);

        list = makeIntList(spr, 10);
        System.out.println(list);
    }
}

makeIntList(Supplier<Integer> s, int n) ๋Š” ์ •์ˆ˜๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
์ฒซ ๋ฒˆ์งธ ์ธ์ž์—์„œ ์ปฌ๋ Œ์…˜ ์ธ์Šคํ„ด์Šค์— ๋‹ด์„ ์ •์ˆ˜์˜ ์ƒ์„ฑ ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

Consumer<T>

๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… T, ๋ฐ˜ํ™˜ ํƒ€์ž… ์—†์Œ

 void accept(T t);
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 2๊ฐœ์ผ ๊ฒฝ์šฐ BiConsumer<T, U>

์ „๋‹ฌ ์ธ์ž๋ฅผ ์†Œ๋น„ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜ํ˜•์ด ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค.
์ „๋‹ฌ๋œ ์ธ์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์•ผ ํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

class ConsumerDemo {
    public static void main(String[] args) {
        Consumer<String> c = s -> System.out.println(s);
        
        c.accept("Pineapple");    // ์ถœ๋ ฅ์ด๋ผ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ธ๋‹ค.
        c.accept("Strawberry");
    }
}

Funtion<T, R>

๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… T, ๋ฐ˜ํ™˜ํƒ€์ž… R

R apply(T t);
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 2๊ฐœ์ธ ๊ฒฝ์šฐ BiFunction<T, U, R>

์ „๋‹ฌํ•œ ์ธ์ž์™€ ๋ฐ˜ํ™˜ ๊ฐ’์ด ๋ชจ๋‘ ์กด์žฌํ•˜๋Š” ๊ฐ€์žฅ ๋ณดํŽธ์ ์ธ ํ˜•ํƒœ์ด๋‹ค.

class FunctionDemo {
    public static void main(String[] args) {
        
    Function<String, Integer> toInt = value -> Integer.parseInt(value);

    Integer number = toInt.apply("100");
    }
}

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์žฅ์ ?

์ด ๋ถ€๋ถ„์€ ์—ฌ๋Ÿฌ ์ž๋ฃŒ๋ฅผ ์ฐพ์•„๋ณด๋ฉด์„œ ์Šค์Šค๋กœ ์ƒ๊ฐํ•ด๋ณธ ๋ถ€๋ถ„์ด๋‹ค.

๊ฐ„๊ฒฐํ•œ ํ‘œํ˜„๊ณผ ๊ฐ€๋…์„ฑ

ํ–‰์œ„๋„ ๊ฐ’(value)์ฒ˜๋Ÿผ ์“ฐ์ผ ์ˆ˜ ์žˆ๋‹ค

1~100๊นŒ์ง€์˜ ์ง์ˆ˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋กœ์ง์„ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ,
ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๊ฐ€์ง€ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

public static int evenSum() {  
   int sum = 0;
   for (int i = 1; i <= 100; i++) {
      if ( i % 2 == 0)
         sum += i;
   }
   return sum;
}
public static int evenSum() {  
   return IntStream.rangeClosed(1, 100)
         .filter(i -> i % 2 ==0)
         .reduce(0, (l, r) -> l + r);
}

filter()์˜ ์„ ์–ธ๋ถ€๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Predicate<> ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์กฐ๊ฑด์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„,
ํ–‰์œ„ ์ž์ฒด๋ฅผ ๊ฐ’์œผ๋กœ ๋ฐ›๊ณ  ์žˆ๋‹ค.
๋˜ํ•œ ์ด ๋•๋ถ„์— filter()์— ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ํ–‰์œ„๊ฐ€ ์–ด๋–ค ๊ฒƒ์ธ์ง€ ๋žŒ๋‹ค์‹์œผ๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋“œ๋Ÿฌ๋‚ด๋ฉฐ
๋„˜๊ฒจ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ง๊ด€์„ฑ์„ ๋†’์ธ๋‹ค๊ณ ๋„ ์ƒ๊ฐํ•œ๋‹ค. (๋งž๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์œผ๋‚˜ ๊ฐœ์ธ์  ์ƒ๊ฐ๐Ÿฅฒ)

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ช…ํ™•ํ•œ ์žฅ์ ์„ ๋งํ•˜๊ณ  ์‹ถ์€๋ฐ,
์ž˜ ์ •๋ฆฌ๊ฐ€ ์•ˆ๋œ๋‹ค.
์ด์— ๋Œ€ํ•ด ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋žจ์˜ ์žฅ์ ์„ ์ฝ์–ด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค(โ“)

์ฐธ๊ณ  ์ž๋ฃŒ