java.util.function

のの·2020년 12월 27일

람다 표현식을 쓸 수 있는 인터페이스는 오직 public 메서드 하나만 가지고 있는 인터페이스여야 한다. 자바 8에서 이러한 인터페이스를 특별히 함수형 인터페이스라고 부르고, 함수형 인터페이스에서 제공하는 단 하나의 추상 메서드를 함수형 메서드라고 부른다.

하지만 프레임워크나 API를 개발해야하는 개발자 입장에서는 람다 표현식을 사용할 수 있도록 메서드가 하나뿐인 인터페이스를 제공해야 하는 번거로움이 생길 수 있다. 이러한 번거로움을 해결하고자 자바 8에서는 일상적인 프로그래밍에서 많이 사용할 법한 패턴을 정리해서 함수형 인터페이스로 만들고 이를 java.util.function 패키지로 제공하고 있다.

forEach문

  • 자바8 이전까지 Collection 등을 순회할 때 Iterator(반복자)를 얻어 순회했지만 자바8 이후부터는 forEach로 가능하다.
  • forEach로 비즈니스 로직을 분리하여 재사용가능
package functionalInterface;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;

class MyConsumer implements Consumer<String>{
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
}

public class ConsumerTest {
    public static void main(String[] args) {
        String[] myArr = {"A","C","B","D"};

        List<String> list = (List) Arrays.asList(myArr);

        /*반복자를 얻어 Collection을 순회

        Iterator<String> iter = list.iterator();
        while(iter.hasNext()){
            System.out.println(iter.next());
        }
        */
        
        // Consumer 인터페이스를 구현한 클래스를 new후 forEach에 사용
        // list.forEach(new MyConsumer());

        /* 익명클래스를 통해 accept 추상메소드를 구현  
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        
        // 람다식 
        //list.forEach(s -> System.out.println(s));
        // 메서드 참조
        list.forEach(System.out::println);
        
    }
}

실행 결과는 모두 다음과 같다.

A
C
B
D

Predicate : 하나의 매개변수를 주는 boolean형을 반환하는 test 메소드가 있다.

public interface Predicate{ boolean test(T t);}

Predicate p = str -> str.isEmpty();
Boolean b = p.test("ojc, asia"); // false

Consumer : 하나의 매개변수를 주는 void 형 accept 메소드가 있다.

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

Consumer< String > c = (s) -> System.out.println(s);
c.accept("ojc.asia"); // ojc.asia

Function: T 타입의 인수를 취하고 R 타입의 결과를 반환하는 추상 메소드 apply가 있다.

public interface Function<T, R> { R.apply(T t);}

Function<String, boolean> f = s -> s.isEmpty();
boolean b = f.apply("ojc.asia"); // false

Supplier: 메소드 인자는 없고 T유형의 결과를 반환하는 추상메소드 get이 있다.

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

Supplier s = () -> "ojc.asia";
String res = s.get(); // ojc.asia

UnaryOperator: 하나의 인자와 리턴타입을 가진다 T -> T

UnaryOperator < String > u = (s) -> "hello~ " + s;
System.out.println(u.apply("ojc.asia")); // hello~ ojc.asia

BinaryOperator: 두개의 인수, 동일한 타입의 결과를 반환하는 추상메소드 apply가 있다.

BinaryOpeator: A binary opeartor from (T,T) -> T

BinaryOpeartor bo = (s1,s2) -> s1 + " , " + s2;
System.out.println(bo.apply("Hello~","ojc.asia");// Hello~ , ojc.asia

package functionalInterface;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class FiTest2 {
    public static void main(String[] args) {
        List<String> cities = Arrays.asList("Seoul", "Busan", "Daegu", "Gwangju", "Inchoen");

        // 하나의 매개변수를 주는 boolean 형을 반환하는 test 메소드가 있다.
        Predicate<String> p = (s) -> s.startsWith("S");

        for (String s : cities) {
            if (p.test(s)) {
                System.out.println("1. Predicate: S로 시작: " + s);
            }
        }

        // 하나의 매개변수를 주는 void 형 accept 메소드가 있다.
        Consumer<String> c = (s) -> {
            if (s.startsWith("S")) {
                System.out.println("2. Consumer: S로 시작: " + s);
            }
        };

        cities.forEach(c);

        // 메소드 인자는 없고 T 유형의 결과를 반환하는 추상메소드 get이 있다.
        Supplier<String> s = () -> cities.toString();
        System.out.println("3. Supplier: " + s.get());

        // T 유형의 인수를 취하고 R 유형의 결과를 반환하는 추상 메소드 apply가 있다.
        Function<String, Boolean> f = str -> str.startsWith("S");

        for (String str : cities) {
            if (f.apply(str)) {
                System.out.println("4. Function: S로 시작:" + str);
            }
        }
    }
}
  
  
  
profile
wannabe developer

0개의 댓글