자바 람다 표현식

16884 단어 java

개요



버전 8에서 구현된 Java Lambda는 메소드의 정의를 표현식으로 기술할 수 있는 함수입니다.

Java8 이전



프로그래머는 논리 코드를 전달하는 인터페이스를 구현해야 합니다.

public class Main {
    interface IGreeter {
        void greet(String name);
    }

    static void delegate(IGreeter iGreeter, String name){
        iGreeter.greet(name);
    }

    public static void main(String[] args) throws Exception {
        // need to put an object implemented the interface 'IGreeter'
        delegate(new IGreeter(){
            public void greet(String name){
                System.out.println("Hello, " + name + "."); // => Hello, Taro.
            }
        }, "Taro");
    }
}


Java8에서



이는 이전보다 더 간단하게 작성할 수 있으며 프로그래머의 가독성을 높였습니다.

public class Main {
    interface IGreeter {
        void greet(String name);
    }

    static void delegate(IGreeter iGreeter, String name){
        iGreeter.greet(name);
    }

    public static void main(String[] args) throws Exception {
        // The below callings print 'Hello, Taro.'
        delegate((name) -> {System.out.println("Hello, " + name + ".");}, "Taro"); // (arg) -> {sentences}

        delegate(name -> {System.out.println("Hello, " + name + ".");}, "Taro"); // arg -> {sentences}  #if only having one arg, it can omit ()

        delegate(name -> System.out.println("Hello, " + name + "."), "Taro"); // arg -> expression
    }
}


"이" 참조



Lambda 메서드와 익명 인터페이스 간에 "this"참조의 의미가 다르므로 주의하십시오.

public class Main {
    private final String value = "aaa";
    interface IPrinter {
        void printValue();
    }

    void delegate(IPrinter iPrinter){
        iPrinter.printValue();
    }

    void callDelegate(){
        delegate(() -> System.out.println("value => " + this.value)); // value => aaa
    }

    public static void main(String[] args) throws Exception {
        // 1) Lambda expression
        new Main().callDelegate(); 

        // 2) Anonymous interface
        new Main().delegate(new IPrinter(){
            private final String value = "bbb";
            public void printValue(){
                System.out.println("value => " + this.value); // value => bbb
            }
        }); 

    }
}


접근 가능한 변수



Lambda 식에서 실질적으로 '최종' 변수에 액세스할 수 있습니다.
'final' 키워드가 없어도 값이 변경되지 않으면 접근 가능합니다.

public class Main {
    interface IPrinter {
        void printValue();
    }

    static void delegate(IPrinter iPrinter){
        iPrinter.printValue();
    }

    public static void main(String[] args) throws Exception {
        int aaa = 100;
        delegate(() -> System.out.println(aaa)); // 100

        //aaa = 200;
        //If the above sentence is uncommented, a compile error will occur with the below error message.
        //Main.java:14: error: local variables referenced from a lambda expression must be final or effectively final
    }
}


상태 저장 람다 표현식



상태가 포함된 람다 식을 사용하려면 두 가지 방법이 있습니다.

1) 인스턴스 필드 사용




public class Main {
    interface ICounter {
        int nextValue();
    }

    private int count; // the default value is zero
    ICounter makeCounter(){
        return () -> count++;
    }

    public static void main(String[] args) throws Exception {
        ICounter iCounter = new Main().makeCounter();
        System.out.println(iCounter.nextValue()); // 0
        System.out.println(iCounter.nextValue()); // 1
        System.out.println(iCounter.nextValue()); // 2
    }
}


2) 참조 객체 사용




public class Main {
    interface ICounter {
        int nextValue();
    }

    private int count; // the default value is zero
    ICounter makeCounter(){
        // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html
        AtomicInteger count = new AtomicInteger();
        return () -> count.getAndIncrement();
    }

    public static void main(String[] args) throws Exception {
        ICounter iCounter = new Main().makeCounter();
        System.out.println(iCounter.nextValue()); // 0
        System.out.println(iCounter.nextValue()); // 1
        System.out.println(iCounter.nextValue()); // 2
    }
}


참조



改訂2版 파페크트자바
https://gihyo.jp/book/2014/978-4-7741-6685-8

좋은 웹페이지 즐겨찾기