자바/함수형 프로그래밍

Functional Interface

끄적끄적 2022. 5. 24. 10:50

Function Interface

package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);
}

아래와 같이 T를 받아 R을 리턴하는 apply 함수 구현하여 사용

public static void main(String[] args) {
    Function<Integer, Integer> myAdder = x -> x + 10;
    int result = myAdder.apply(5);
    System.out.println(result);
}

 

ByFunction Interface

package java.util.function;
import java.util.Objects;

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

아래와 같이 두개의 매개변수 T, U를 받아 R을 리턴하는 함수

public static void main(String[] args) {
    BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
    int result = add.apply(3, 5);
    System.out.println(result);
}

Supplier Interface : 입력값 없이 리턴만 있는 get 함수

package java.util.function;

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

아래와 같이 get함수 호출해서 사용가능

public static void main(String[] args) {	
    Supplier<Double> myRandomDoubleSupplier = () -> Math.random();
    printRandomDoubles(myRandomDoubleSupplier, 5);
}

public static void printRandomDoubles(Supplier<Double> randomSupplier,
        int count) {
    for (int i = 0; i < count; i ++) {
        System.out.println(randomSupplier.get());
    }
}

Consumer Interface : 입력만 받고 리턴은 하지 않는 accept 함수

package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

아래와 같이 accept함수 선언 후 사용

public static void main(String[] args) {
    Consumer<String> myStringConsumer = (String str) -> 
        System.out.println(str);
    myStringConsumer.accept("hello");
    myStringConsumer.accept("world");

    List<Integer> integerInputs = Arrays.asList(4, 2, 3);
    Consumer<Integer> myIntegerProcessor = x -> 
        System.out.println("Processing integer " + x);
    process(integerInputs, myIntegerProcessor);
    Consumer<Integer> myDifferentIntegerProcessor = x -> 
        System.out.println("Processing integer in different way " + x);
    process(integerInputs, myDifferentIntegerProcessor);

    Consumer<Double> myDoubleProcessor = x ->
        System.out.println("Processing double " + x);
    List<Double> doubleInputs = Arrays.asList(1.1, 2.2, 3.3);
    process(doubleInputs, myDoubleProcessor);
}
	
public static <T> void process(List<T> inputs, Consumer<T> processor) {
    for (T input : inputs) {
        processor.accept(input);
    }
}

BiConsumer

package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface BiConsumer<T, U> {

    void accept(T t, U u);
}

입력을 두개 받고, 리턴은 없는 경우 accept

public static void main(String[] args) {
    BiConsumer<Integer, Double> myDoubleProcessor = 
            (index, input) -> 
                System.out.println("Processing " + input + " at index " + index);
    List<Double> inputs = Arrays.asList(1.1, 2.2, 3.3);	
    process(inputs, myDoubleProcessor);
}

public static <T> void process(List<T> inputs, BiConsumer<Integer, T> processor) {
    for (int i = 0; i< inputs.size(); i++) {
        processor.accept(i, inputs.get(i));
    }
}

Predicate Interface : 하나의 값을 받아 boolean 리턴하는 test함수

package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);
}

활용법 : or(), and(), negate() 로 Predicate를 변형해서도 사용가능

public static void main(String[] args) {
    Predicate<Integer> isPositive = x -> x > 0;
    System.out.println(isPositive.test(-10));

    List<Integer> inputs = Arrays.asList(10, -5, 4, -2, 0, 3);
    System.out.println("Positive number: " + filter(inputs, isPositive));
    System.out.println("Non-positive number: " + filter(inputs, isPositive.negate()));
    System.out.println("Non-negative number: " 
            + filter(inputs, isPositive.or(x -> x == 0)));
    System.out.println("Positive even numbers: " 
            + filter(inputs, isPositive.and(x -> x % 2 == 0)));
}

public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
    List<T> output = new ArrayList<>();
    for (T input : inputs) {
        if (condition.test(input)) {
            output.add(input);
        }
    }
    return output;
}

Comparator Interface

package java.util;

@FunctionalInterface
public interface Comparator<T> {

    int compare(T o1, T o2);
}

비교 함수로서, Collections 에 비교함수 매개변수 등으로 사용

public static void main(String[] args) {
    List<User> users = new ArrayList<>();
    users.add(new User(3, "Alice"));
    users.add(new User(1, "Charlie"));
    users.add(new User(5, "Bob"));
    System.out.println(users);

    Comparator<User> idComparator = (u1, u2) -> u1.getId() - u2.getId();
    Collections.sort(users, idComparator);
    System.out.println(users);

    Collections.sort(users, (u1, u2) -> u1.getName().compareTo(u2.getName()));
    System.out.println(users);
}
반응형