티스토리 뷰

개발/Java

자바 람다식

Beemo_ 2020. 12. 19. 14:57

람다식?

 - 메서드를 하나의 식으로 표현한 것

 - 메서드의 이름과 반환값이 없어지므로, 익명함수라고도 함

 

 

람다식 작성법

 

반환타입 메서드이름 (매개변수) {

    //내용

}

 

(매개변수) -> {

    //내용

}

 

int add(int a, int b) {

    return a + b;

}

 

(int a, int b) -> {

    return a + b;

}

 

(a, b) -> a + b

 

함수형 인터페이스

 

Type t = (int a, int b) -> a + b;

 

interface Function {
    int add(int a, int b);
}

Function function = new Function() {
      @Override
      public int add(int a, int b) {
          return a + b;
      }
};
function.add(1,3);

 

interface LambdaInterface {
    int add(int a, int b);
}

LambdaInterface lambdaInterface = (int a, int b) -> {return a + b;};
lambdaInterface.add(1,3);

 - 인터페이스를 통해 람다식을 다룸

 - 람다식을 다루기 위한 인터페이스를 함수형 인터페이스 라고 함

 - 함수형 인터페이스는 오직 하나의 추상 메서드만 정의 되어야 한다는 제약이 있음

 

@FunctionalInterface
interface LambdaInterface {
    int add(int a, int b);
}

 - @FunctionalInterface 어노테이션을 선언하면 함수형 인터페이스의 제약에 맞게 정의하였는지 확인해줌

 

람다식의 외부 변수 참조

@FunctionalInterface
interface LambdaInterface {
    void method();
}

class Outer {
    int val = 10;

    class Inner {
        int val = 20;

        void method(int i) { //final
            int val = 30; //final
            Outer.this.val = 40;
            this.val = 30;
            //val = 20; - 에러
            //i = 40; - 에러
            LambdaInterface lambdaInterface = () -> {
                System.out.println("i : " + i);
                System.out.println("val : " + val);
                System.out.println("this.val : " + this.val);
                System.out.println("Outer.this.val : " + Outer.this.val);
            };
            lambdaInterface.method();
        }
    }
}

 - 람다식내에서 참조하는 지역변수는 상수로 간주

 - 외부변수들은 상수로 간주되지 않으므로 값의 변경이 가능

 

 void method(int i) { //final
            int val = 30; //final
            Outer.this.val = 40;
            this.val = 30;
            //val = 20; - 에러
            //i = 40; - 에러
            LambdaInterface lambdaInterface = (i) -> { //에러
                System.out.println("i : " + i);
                System.out.println("val : " + val);
                System.out.println("this.val : " + this.val);
                System.out.println("Outer.this.val : " + Outer.this.val);
            };
            lambdaInterface.method();
        }

 - 외부 지역변수와 같은 이름의 람다식 매개변수는 허용되지 않음

 

java.util.function

 

Runnable runnable = () -> {}; // void run();
Supplier<String> supplier = () -> {return "string";}; //T get();
Consumer<String> consumer = (String t) -> {}; // void accept(T t);
Function<String, Integer> function = (String t) -> {return 5;}; // R apply(T t) : R은 반환 타입
Predicate<String> predicate = (String t) -> {return false;}; // boolean test(T t);

 - java.util.function 패키지안에 미리 정의 된 함수형 인터페이스

 - 매번 새로운 인터페이스를 정의 할 필요없이 해당 패키지의 인터페이스를 활용하는 게 좋음

   - 메서드 이름의 통일

   - 재사용성, 유지보수 측면에서 효율

BiPredicate<String, String> biPredicate = (String t, String u) -> {return false;}; 
//매개변수가 2개면 앞에 Bi가 붙은 interface사용

 

합성과 결합

 

합성

andThen, compose

 Function <String, Integer> f = (s) -> Integer.parseInt(s);
 Function <Integer, String> g = (i) -> Integer.toBinaryString(i);
 Function <String, String> h = f.andThen(g); //f 수행 후 g를 수행
 Function <Integer, Integer> h2 = g.andThen(f); //g 수행 후 f를 수행
        
 h = g.compose(f); //f 수행 후 g를 수행
 h2 = f.compose(g);//g 수행 후 f를 수행

결합

and, or, negate

Predicate<Integer> p = i-> i < 100;
Predicate<Integer> q = i-> i < 200;
Predicate<Integer> r = i-> i % 2 == 0;
Predicate<Integer> notP = p.negate(); // i >= 100
        
// 100 <= i && (i < 200 || i % 2 == 0) 
Predicate<Integer> result = notP.and(q.or(r));
System.out.println(result.test(150)); // true

 

'개발 > Java' 카테고리의 다른 글

Effective Java 3/E - 싱글턴을 만드는 방법  (0) 2021.01.16
Effective Java 3/E - 정적 팩터리 메서드  (0) 2021.01.14
자바 스트림 -2  (0) 2021.01.01
자바 스트림 -1  (0) 2020.12.26
자바 객체를 생성하는 3가지 방법  (0) 2020.11.27
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함