2018-7-5 함수형 인터페이스

정의되어 있는 함수형 인터페이스

미리 정의되어 있는 함수형 인터페이스

@FunctionalInterface
public interface Predicate<T> {
	boolean test(T t);
}
  • 위의 코드와 같이 미리 정의되어 있는 함수형 인터페이스들이 있다.
  • Predicate<T> booelan test(T t)
  • Supplier<T> T get()
  • Consumer<T> void accept(T t)
  • Function<T, R> R apply(T t)와 같은 대표적인 함수형 인터페이스들이 있다.

Predicate<T>

  • boolean test(T t); // 전달된 인자를 대상으로 true, false를 판단할때 사용
public 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);
    }
}
  • boolean test(Integer t) 메소드 정의에 해당하는 람다식을 작성해서 전달을 한다.
Predicate<T>를 구체화하고 다양화 한 인터페이스들
  1. InPredicate boolean test(int value)
  2. LongPredicate boolean test(long value)
  3. DoublePredicate boolean test(double value)

Supplier<T>

  • T get(); // 단순히 무엇인가를 반환할때
public 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);
    }
}
//result
[25, 5, 47, 20, 10]
[46, 31, 1, 48, 49, 46, 1, 43, 6, 9]
  • n은 리스트의 갯수를 담는다.
  • Supplier s의 정의를 밑에 Supplier<Integer> spr을 통해서 정의를 했다.
  • spr은 1-50사이의 임의의 정수를 리턴한다.

Consumer<T>

  • void accept(T t); // 전달된 인자 기반으로 ‘반환’이외의 다른 결과를 보일때
public class ConsumerDemo {
    public static void main(String[] args) {
        Consumer<String> c = s -> System.out.println(s);
        c.accept("Pineapple");
        c.accept("Strawberry");
    }
}
//result
Pineapple
Strawberry
public class ObjIntConsumerDemo {
    public static void main(String[] args) {
        ObjIntConsumer<String> c = (s, i) -> System.out.println(i + ". " + s);
        int n = 1;
        c.accept("Toy", n++);
        c.accept("Robot", n++);
        c.accept("Candy", n++);
    }
}
//result
1. Toy
2. Robot
3. Candy

Function<T, R>

  • R apply(T t) // 전달 인자와 반환 값이 모두 존재할 때
public class FunctionDemo {
    public static void main(String[] args) {
        Function<String, Integer> f = s -> s.length();
        System.out.println(f.apply("Robott"));
        System.out.println(f.apply("Box"));
    }
}
//result
6
3

RemoveIf

  • Collection<E> 인터페이스에 다음과 같은 메소드가 정의되어있다. default boolean removeIf(Predicate<? super E> filter)
  • ArrayList<Integer>인스턴스를 생성하면 그 안에 존재하는 removeIf메소드의 E는 다음과 같이 Integer로 결정된다.
  • public boolean removeIf(Predicate<? super Integer> filter) { … }
  • removeIf의 역할은 컬렉션 인터페이스에 저장된 인스턴스를 test메소드의 인자로 전달했을 때, true가 반환되는인스턴스는 모두 삭제하겠다는 뜻이다.
public class RemoveIfDemo {
    public static void main(String[] args) {
        List<Integer> ls1 = Arrays.asList(1, -2, 3, -4, 5);
        ls1 = new ArrayList<>(ls1);

        List<Double> ls2 = Arrays.asList(-1.1, 2.2, -3.3, -4.4, 5.5);
        ls2 = new ArrayList<>(ls2);

        Predicate<Number> p = n -> n.doubleValue() < 0.0; // 삭제의 조건
        ls1.removeIf(p);
        ls2.removeIf(p); // 인스턴스에 전달

        System.out.println(ls1);
        System.out.println(ls2);
    }
}
//result
[1, 3, 5]
[2.2, 5.5]
Written on July 5, 2018