JAVA - Collection(3) 함수형 인터페이스

이상해씨·2022년 7월 30일
0

웹 풀스택(JAVA)

목록 보기
13/54

✔함수형 인터페이스

  • 함수형 인터페이스(람다식 인터페이스) : 1개의 추상 메서드를 갖는 인터페이스.
    • 제약 조건 : 오직 하나의 추상 메서드만 정의되어 있어야 한다.
      • static 메서드와 default 메서드의 개수에는 제약이 없다.
    • 람다식 표현시 데이터 추론이 가능하여 매개변수 데이터 타입 생략 가능.
interface Test{
	// 함수형 인터페이스를 위해 1개의 추상 메서드만 작성.
	void funcInterface();
    // static, default 메서드는 제약이 없음.
    static void staticFunc(){}
  	default void defaultFunc(){}
}
  • 일급 객체 : 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
    • 변수에 할당(assignment)할 수 있다.
    • 다른 함수를 인자(argument)로 전달 받는다.
    • 다른 함수의 결과로서 리턴될 수 있다.
  • 일급 객체를 쓸 수 있는 언어 : 함수형 프로그래밍 언어
    • 자바는 일급 객체 사용 불가능 : 람다식으로 함수를 넘기는 것처럼 보이지만 실상은 객체를 넘기는 것.

1. 자바에서 제공하는 함수형 인터페이스

  • Runnable - void run() : 매개변수 없음. 반환값 없음.
    • Runnable helloWorld = () -> System.out.println("Hello World!");
  • Supplier< T > - T get() : 매개변수 없음. 반환 값 있음.
    • Supplier<String> supplyFood = () -> "스테이크 생성";
  • Consumer< T > - void accept(T t) : 매개변수 1개. 반환 값 없음.
    • Consumer<String> consumeFood = (food) -> System.out.println(food + "를 먹었습니다.");
  • Function< T, R > - R apply(T t) : 매개변수 1개. 반환 값 있음.
    • Function<Integer, Integer> ourSelfSum = (a) -> a + a;
  • Predicate< T > - boolean test(T t) : 매개변수 1개. 반환 값 있음(boolean, 조건식을 표현하는데 사용)
    • Predicate<Integer> lessThanTen = (number) -> number < 10;
  • BiConsumer<T, U> - void accept(T t, U u) : 매개변수 2개. 반환 값 없음
    • BiConsumer<String, Integer> consumeFood2 = (food, quantity) -> System.out.println(food + "를 " + quantity + "개 먹었습니다.");
  • BiFunction<T, U, R> - R apply(T t, U u) : 매개변수 2개. 반환 값 있음
    • BiFunction<Integer, Integer, Integer> multiply = (x, y) -> x * y;
  • BiPredicate<T, U> - boolean test(T t, U u) : 매개변수 2개. 반환 값 있음(boolean, 조건식을 표현하는데 사용)
    • BiPredicate<Integer, Integer> lessThan = (number, base) -> number < base;
  • UnaryOperator< T > - T apply(T t) : 매개변수 1개. 반환 값 있음. (매개변수, 반환 값 타입 같음)
    • UnaryOperator<Integer> ourSelfSum = (a) -> a + a;
  • BinaryOperator< T > - T apply(T t1, T t2) : 매개변수 2개. 반환 값 있음. (매개변수, 반환 값 타입 같음)
    • BinaryOperator<Integer> multiply = (x, y) -> x * y;

2. Collection에서의 함수형 인터페이스

  • Collection에는 함수형 인터페이스를 매개변수로 가지는 메서드가 있다.
    • 람다식으로 구성하여 원하는 형식으로 사용 가능.
  • List의 함수형 인터페이스 활용
    • void forEach(Consumer< T > action) : 모든 요소에 작업 action을 수행.
      • list.forEach(name -> System.out.print(name + ", "));
    • boolean removeIf(Predicate< E > filter) : 조건에 맞는 요소를 삭제
      • list.removeIf(name -> name.contains("이") || name.contains("박"));
    • void replaceAll(UnaryOperator< E > operator) : 모든 요소를 변환하여 대체
      • list.replaceAll(name -> name + " 교육생");
  • Map의 함수형 인터페이스 활용
    • void forEach(BiConsumer<K, V> action) : 모든 요소에 작업 action을 수행
      • map.forEach((key, value) -> System.out.print(key + ":" + value + ", "));
    • void replaceAll(BiFunction<K, V, V> f) : 모든 요소에 치환작업 f를 수행
      • map.replaceAll((key, value) -> value + 1);
    • V compute(K key, BiFunction<K, V, V> f) : 지정된 키의 값에 작업 f를 수행
      • int age = map.compute("김싸피", (key, value) -> value + 10);
    • V computeIfAbsent(K key, Function<K, V> f) : 키가 없으면 작업 f 수행 후 추가
      • age = map.computeIfAbsent("홍길동", (key) -> 1);
    • V computeIfPresent(K key, BiFunction<K, V, V> f) : 지정된 키가 있을 때 작업 f를 수행
      • age = map.computeIfPresent("홍길동", (key, value) -> value + 20);
    • V merge(K key, V value, BiFunction<V, V, V> f) : 모든 요소에 병합작업 f를 수행
      • age = map.merge("홍길동", 10, (original, newValue) -> original + newValue);

3. 다양한 함수형 인터페이스

  • Coposition(합성, 결합) - Function : apply()
Function<String, Integer> f = (s) -> Integer.parseInt(s, 16);  // 16진수 문자열을 정수로 변환
Function<Integer, String> g = (i) -> Integer.toBinaryString(i);  // 정수를 이진수 문자열로 변환
  1. andThen : f 수행 후 g 수행
    • Function<String, String> h = f.andThen(g);
  2. compose : g 수행 후 f 수행
    • Function<Integer, Integer> i = f.compose(g);
  3. identity : 항등 함수 (거의 사용되지 않는다.)
    • Function<String, String> j = Function.identity();
  • Predicate Composition - Predicate : test()
Predicate<Integer> overZero = (number) -> 0 <= number;
Predicate<Integer> lessThanTen = (number) -> number < 10;
Predicate<Integer> even = (number) -> number % 2 == 0;
  1. and : 둘 모두 참이면 참.
    • overZero.and(lessThanTen).test(6);
  2. or : 둘 중 하나가 참이면 참.
    • lessThanTen.or(even).test(12);
  3. negate(부정하다) : 거짓이면 참.
    • lessThanTen.negate().test(20)
  4. isEqual : 둘이 같다면 참.
    • Predicate.isEqual(name1).test(name2);
  • 기본형 데이터 함수형 인터페이스 : A, B는 기본형 부분.
    1. A To B Function : DoubleToIntFunction f1 = (doubleValue) -> (int) doubleValue;
    2. To B Function : ToIntFunction<Double> f2 = (doubleValue) -> doubleValue.intValue();
    3. A Function : DoubleFunction<Integer> f3 = (doubleValue) -> (int) doubleValue;
    4. Obj A Consumer : ObjIntConsumer<Double> f4 = (doubleValue, intValue) -> System.out.println(doubleValue * 10 + ", " + intValue * 10);

4. 메서드 참조

  • 메서드 참조 : 람다식이 하나의 메서드만 호출하는 경우 메서드 참조 사용 가능.
    • 람다식을 더욱 간결하게 표현하는 방법
    • 클래스이름::메소드이름or 참조변수이름::메소드이름
      • (ex) (base, exponent) -> Math.pow(base, exponent);
        • Math::pow;
      • (ex) Function<String, Boolean> func = (a) -> obj.equals(a); // 람다 표현식
        • Function<String, Boolean> func = obj::equals(a)
profile
후라이드 치킨

0개의 댓글