본문 바로가기
JAVA

함수형 인터페이스

by 공부 안하고 싶은 사람 2021. 2. 19.
반응형

인터페이스에 함수가 하나라면 @FunctionalInterface을 붙여 람다식으로 활용가능

@FunctionalInterface
interface RunSomething {
    void doIt();
}
RunSomething runSomething = new RunSomething() {
    @Override        
    public void doIt() {
        System.out.println("Hello, I'm DolphaGo");        
    }    
};
RunSomething runSomething = () -> System.out.println("Hello, I'm DolphaGo")

기본 함수형 인터페이스

Function<Integer,Integer> plus10= (i) -> i+10; // -> UnaryOperator<Integer> plus10 = (i) ->(i+10);
Function<Integer,Integer> multiply2 = (i) -> i*2;
Function<Integer, Integer> func = plus10.andThen(multiply2);
System.out.println(func.apply(2)); // -> 생성된 람다 함수에 2를 넣어 실행(순서대로)
  • 리턴값 X

    Consumer<Integer> print=(i)-> System.out.println(i);
    print.accept(10);
  • 인자 X

    Supplier<Integer> get10 = () -> 10;
    System.out.println(get10.get());
  • boolean

    Predicate<String> startWithDolphaGo = (s) -> s.startsWith("DolphaGo");
    System.out.println(startWithDolphaGo.test("DolphaGo's Blog"));

가능한 모든 속성으로 필터링(일반적방법)

private static List<Apple>filterApples(List<Apple> apples, Color color, int weight, boolean flag) {
    List<Apple> result=new ArrayList<>();
    for(Apple apple:apples){
        if((flag && apple.getColor().equals(color)) || (!flag && apple.getWeight()>=weight) ) {            
            result.add(apple);        
        }    
    }    
    return result; 
}

List<Apple> greenApples=filterApples(apples,Color.GREEN,0,true);
List<Apple> largeApples=filterApples(apples,null,150,false);

람다사용, 리스트형식 추상화(함수형)

private static <T> List<T> filter(List<T> list, Predicate<T> p) {
    List<T> result = new ArrayList<>();
    for (T e : list) {
        if (p.test(e)) 
            result.add(e);
    }    
    return result; 
}

List<Apple> apples = List.of(new Apple(100, Color.GREEN), new Apple(150, Color.RED));
List<Banana> bananas = List.of(new Banana(100, Color.GREEN), new Banana(150, Color.GREEN));
List<Integer> numbers= List.of(3,6,1,2,3,2,1,6,7,2,3,4,6,4,3,2,34,123);
List<Apple> filteredApples = filter(apples, (Apple apple) -> Color.RED.equals(apple.getColor()));
List<Banana> filteredBananas= filter(bananas,(Banana banana) -> banana.getWeight()>150);
List<Integer> filteredNumbers = filter(numbers, (Integer i) -> i.intValue() % 2 == 0);

특징

형식추론 - 컴파일러는 람다의 시그니처도 추론할 수 있습니다. 결과적으로 컴파일러는 람다 표현식의 파라미터 형식에 접근할 수 있으므로 람다 문법에서 이를 생략할 수 있습니다. (인자의 자료형 생략)

지역 변수 사용 - final로 선언된 지역변수를 body({}안)에서 사용가능

메서드 참조 - 정의를 재활용

list.sort((o1,o2) -> Integer.compare(o1,o2) );
list.sort(Integer::compare);

생성자 참조

Supplier<Apple> supplier = Apple::new;
Apple apple = supplier.get();

Function<Integer, Apple> function = Apple::new;
Apple apple = function.apply(100);
public class AppleComparator implements Comparator<Apple> {
    @Override
    public int compare(Apple o1, Apple o2) {
        return Integer.compare(o1.getWeight(),o2.getWeight());
    }
}
apples.sort(new AppleComparator()); //Apple을 weight별로 비교해서 apples를 sort하라

apples.sort(new Comparator<Apple>() {
    @Override
    public int compare(Apple o1, Apple o2) {
        return Integer.compare(o1.getWeight(), o2.getWeight());
    }
}); //익명 클래스 활용

apples.sort((o1, o2) -> Integer.compare(o1.getWeight(), o2.getWeight()) ); //람다식 사용

apples.sort(Comparator.comparing(Apple::getWeight)); //메서드 참조

유용한 람다 메서드

  • 비교에 사용할 키 추출

    Comparator<Apple> c = Comparator.comparing(Apple::getWeight)
  • 역정렬

    apples.sort(comparing(Apple::getWeight).reversed()
               .thenComparing(Apple::getColor)); //2번째 정렬 포인트 추가
  • Predicate 조합

    Predicate<Apple> redApple = apple -> apple.getColor().equals(Color.RED);
    Predicate<Apple> redAndHeavyAppleOrGreen = redApple.and(apple -> apple.getWeight() > 150)
                                            .or(apple -> apple.getColor().equals(Color.GREEN));
    
    Predicate<Apple> negate =redApple.negate();//조건 반전
    List<Apple> collect = apples.stream().filter(negate).collect(Collectors.toList());
  • Function 조합

    Function<Integer, Integer> f = x -> x + 1;
    Function<Integer, Integer> g = x -> 2 * x;
    
    Function<Integer,Integer> h1= f.andThen(g); //f->g
    Function<Integer,Integer> h2= g.compose(f); //g->f

 

참고 :https://blog.naver.com/PostView.nhn?logId=adamdoha&logNo=222165071779&parentCategoryNo=&categoryNo=73&viewDate=&isShowPopularPosts=false&from=postList

728x90
반응형

'JAVA' 카테고리의 다른 글

SOLID  (0) 2021.06.28
디자인 패턴  (0) 2021.06.28
인코딩 변환  (0) 2021.04.29
스트림  (0) 2021.02.19
Jackson Library (ObjectMapper)  (0) 2021.02.09

댓글