Back-end/JAVA

JAVA - Functional Interface

개발자 키우기 2023. 10. 15. 19:05

자바의 함수형 인터페이스는 단 하나의 추상 메서드를 가지는 인터페이스를 말한다.

 

주로 람다 표현식을 사용하여 사용하며 함수형 프로그래밍을 지원하기 위해 도입되었다.


java.util.function.Predicate<T>

 

boolea test(T t) / 매개값 ( o ) / 리턴값( o )

 

매개값을 조사해서 boolean 값을 리턴하는 역할로 주로 조건을 검사하거나 필터링할 때 사용

 

public class PredicateExample {
  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(-1, 5, -7, 10, 0, 3);

    Predicate<Integer> isPositive = (n) -> n > 0;  // 조건식

    for (Integer number : numbers) {
      if (isPositive.test(number)) {  // 조건 검사 ( ture, false 반환 )
        System.out.println(number);
      }
    }
  }
}

 

default  method

 

and() = && / or() = || / negate() = !

 

java.util.function.Predicate.isEqual(Object targetRef)

 

target 값과 비교하는 값이 같으면 true, 다르면 false 반환

 

List<String> names = List.of("Alice", "Bob", "Charlie", "David");

String target = "Bob";
Predicate<String> isEqualToTarget = Predicate.isEqual(target);

List<String> filteredNames = names.stream()
  .filter(isEqualToTarget)
  .collect(Collectors.toList());

System.out.println(filteredNames); // ["Bob"]

java.util.function.Consumer<T>

 

 

void accept(T t) / 매개값( o ) / 리턴값( x )

 

매개값을 소비하는 역할

 

public class ConsumerExample {
  public static void main(String[] args) {
    Consumer<String> printName = (name) -> System.out.println(name); // 매개값을 소비할 방법

    printName.accept("Alice"); // 매개값 소비
    printName.accept("Bob");
    printName.accept("Charlie");
  }
}

java.util.function.Supplier<T>

 

T get() / 매개값( x ) / 리턴값( o )

 

데이터를 공급하는 역할로 값을 생성하여 반환할 때 사용

 

public class SupplierExample {
  public static void main(String[] args) {
    Supplier<Integer> randomSupplier = () -> new Random().nextInt(100); // 값 생성

    int randomNumber = randomSupplier.get(); // 값 반환
    System.out.println("Random Number: " + randomNumber);
  }
}

java.util.function.Function<T, R>

 

R apply (T t) / 매개값( o ) / 리턴값 ( o )

 

매개값을 매핑(타입면환) 하여 리턴하는 역할로 데이터의 변환과 처리에 사용

 

public class FunctionExample {
  public static void main(String[] args) {
    Function<String, Integer> stringToInt = (str) -> Integer.parseInt(str);

    String numberStr = "42";
    Integer number = stringToInt.apply(numberStr);

    System.out.println("Parsed Integer: " + number);
  }
}

java.util.function.Comparator<T>

 

int compare (T o1, T o2) / 매개값 ( o ) / 리턴값 ( o )

 

매개값 두 개를 받아서 비교하는 역할로 객체를 다양한 기준에 따라 비교하여 정렬할 때 사용

 

o1과 o2를 비교하여 o1이 o2 보다 작으면 음수를 반환

 

o1과 o2를 비교하여 o1이 o2 보다 크면 양수를 반환

 

o1과 o2를 비교하여 o1이 o2과 같으면 0을 반환

 

class Person {
  private String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }

  @Override
  public String toString() {
    return name + " (Age: " + age + ")";
  }
}

public class ComparatorExample {
  public static void main(String[] args) {
    List<Person> people = new ArrayList<>();
    people.add(new Person("Alice", 30));
    people.add(new Person("Bob", 25));
    people.add(new Person("Charlie", 35));

    Collections.sort(people, (person1, person2) -> Integer.compare(person1.getAge(), person2.getAge()));

    people.forEach(System.out::println);
  }
}

 

java.lang.Comparable<T> 

 

int compareTo ( T o )

 

예시 ) a.compareTo(b)

 

Comparator과 유사한 Comparable은 자기가 가지고 있는 값과 파라미터로 받은 인자를 비교


java.lang.Runnable

 

void run() / 매개값 ( x ) / 리턴값 ( x )

 

메인스레드가 아닌 새로운 스레드를 생성해서 실행할 코드 블록을 나타내는 역할

 

public class RunnableExample {
  public static void main(String[] args) {
    Runnable task = () -> {
      for (int i = 0; i < 1000; i++) {
        System.out.println("Task: " + i);
      }
    };

    Thread thread1 = new Thread(task);
    Thread thread2 = new Thread(task);
    thread1.start();
    thread2.start();
  }
}

java.util.concurrent.Callable(V)

 

V call() / 매개값 ( x ) / 리턴값 ( o )

 

메인스레드가 아닌 새로운 스레드를 생성해서 실행할 코드 블럭을 나타내며 반환값을 내는 역할

 

주로 스레드 풀과 함께 사용되며 예외를 던질 수 있다.

 

public class CallableExample {
  public static void main(String[] args) throws Exception {
    Callable<Integer> task = () -> {
      int result = 0;
      for (int i = 1; i <= 100; i++) {
        result += i;
      }
    return result;
  };

  ExecutorService executor = Executors.newSingleThreadExecutor();
  Future<Integer> future = executor.submit(task);

  Integer result = future.get();
  System.out.println("결과: " + result);

  executor.shutdown();
  }
}

java.util.function.*Operator<T>

 

Function 인터페이스와 유사하지만 매개 타입과 같은 타입을 리턴

 

정적 메서드로 minBy() 와 maxBy() 가 있음


 

andThen() / compose()

 

함수형 프로그래밍에서 함수를 조합하고 연결하는 데 사용되는 메서드

 

andThen()

 

두 개의 함수를 순차적으로 연결

 

Consumer / Function / *Operator 사용 가능

 

Function<String, String> toUpper = str -> str.toUpperCase();
Consumer<String> print = str -> System.out.println(str);

Function<String, String> upperAndPrint = toUpper.andThen(result -> {
  print.accept(result);
  return result;
});

upperAndPrint.apply("hello"); // "HELLO"가 출력됩니다.

compose()

 

두개의 함수를 역순으로 연결

 

Function / *Operator 사용가능

 

Function<String, String> toUpper = str -> str.toUpperCase();
Function<String, String> addExclamation = str -> str + "!";

Function<String, String> upperAndExclaim = addExclamation.compose(toUpper);

String result = upperAndExclaim.apply("hello"); // "HELLO!"를 반환합니다
System.out.println(result);