[Java] 람다 시작

14290 단어 java8Java

인용문


Java에서 루틴을 실행하기 위해 Thread 클래스의 하위 클래스를 계승하는 방법을 사용합니다.
Runnable 인터페이스가 설치된 하위 클래스를 사용하는 방법이 있습니다.
이번에는 람다식에 대한 간단한 설명을 위해 후자를 예로 들자.
Function.java
public class Function implements Runnable{
    @Override
    public void run() {
        // スレッドで処理する内容
        System.out.println("hello!");
    }
}
Main.java
public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new Function());
        thread.start();
        System.out.println("finish!");
    }
}
나는 출력이 이렇게 될 것이라고 생각한다.
finish!
hello!
Thread 클래스와 Runnable 인터페이스의 관계는
GoF 디자인 모드의 Strategy 모드 디자인을 사용합니다.
Strategy 모델은 대체적으로 "교체할 수 있는 알고리즘을 실현하는"디자인이다.
원래 하나밖에 없는 반의 전체적인 절차를 처리하는 반을 맡고
구체적인 알고리즘을 담당하는 유형으로 나누어 고려한다.
Strategy 모드를 사용하여 사용면(Thread 클래스)
사용 측면(Runnable 인터페이스를 구현한 클래스)
직접적인 관계가 없기 때문에 나중에 바꿀 수 있는 알고리즘을 실현할 수 있다.
(Strategy 모드에 대해 자세히 알고 있는 사람은 볼 수 있다여기

그러나 인터페이스를 실현하는 클래스는 복잡하다(UML 그림의 FunctionHard 클래스)와
일부 클래스(UML 그림의 FunctionEasy 클래스)는 간단한 코드로 완성할 수 있다.
간단한 코드만 있으면 되는데, 하나하나 반을 새로 만들다
번거롭지 않게 정의해야 하나요?듣자니

람다식의 효력


서문에서 제기된 문제점을 해결하기 위해 자바 SE8에서 가져온 람다식을 이용한다.
다음 코드는 FunctionEasy 클래스를 만드는 대신 람다식으로 바꾸는 코드입니다.
Lambda.java
public class Lambda {
    public static void main(String[] args) {
        Runnable r = () -> System.out.println("hello!");
        Thread thread = new Thread(r);
        thread.start();
        System.out.println("finish!");
    }
}
이렇게 하면 돼!
"실례화된 함수형 인터페이스에서
번거로운 기술은 필요 없어도 되는 기법이다.
하나의 방법만 실현하는 인터페이스는 "함수형 인터페이스"이다
SAM(Single Abstarct Method) 인터페이스라고도 합니다.
SAM에서 알 수 있듯이 하나의 추상적인 방법만 있기 때문에
람다 공식은 어떤 방법을 실시합니까?매개 변수와 반환 값은 어떻습니까?
추론할 수 있다. 방법명을 하나하나 결정할 필요는 없다.
인터페이스를 실현하는 종류를 준비하지 않으면 다태성을 실현할 수 있다.

익명류와 λ 표현식


Java8은 이전에 익명 클래스를 통해 이루어졌습니다.
익명류는 때때로 무명류라고도 불린다.

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello!");
            }
        }
길고 가독성이 떨어진다.
Java8에는 보다 간단하게 기술할 수 있는 람다식이 나와 있습니다.
        Runnable r = () -> {
            System.out.println("hello!");
        }
람다식의 선언은 자변량 선언과 처리 블록으로 구성되어 있으며 다음과 같다.
     ( 引数 ) -> { 処理; };
"->"을 화살표 연산자로 합니다.

람다식 줄임말


람다식에서 생략할 수 있는 것이 있다.
다음은 원형을 예로 들자.
원형

        Sample sample = (String a) -> { System.out.println(a);};

생략 표기법 1


매개변수가 하나만 있으면 괄호 "()"를 생략할 수 있습니다.
또한 매개 변수의 유형은 유형 추리를 할 수 있기 때문에 생략할 수 있다.
생략 표기법 1
        Sample sample = a -> { System.out.println(a);};

생략 표기법 2


또한 메소드 바디가 1행일 때 중괄호 "{}"와 문장 끝의 세미콜론 ";대화상자, 사용자 정의 형식을 정의할 수 있습니다.
return 문장도 return을 생략할 수 있습니다.
생략 표기법 2
        Sample sample = a -> System.out.println(a);

생략번호


그 밖에 매개 변수를 추론할 수 있다면 방법은 호출된다
클래스 이름: 방법 이름
객체 이름:메소드 이름
이렇게 하면 생략할 수 있다.
생략번호
        Sample sample = System.out::println;

λ 표현식 변수 범위


주의1


방법에 설명된 국부 변수와 같은 이름의 변수는 람다식의 자변수 이름으로 사용할 수 없습니다.
다음은 컴파일 오류입니다.
public class Sample {
    public static void main(String[] args) {
        String a = "sample";
        Function f = a -> System.out.println(a); // エラー
        // 略
    }
}
a라는 변수명은 이미 국부 변수로 선언되었기 때문에 람다식의 자변수명으로 사용할 수 없다.

주의2


람다식에서 람다식 밖에서 국부 변수를 설명하기 위해서는 국부 변수는final이어야 한다.
final 수식자가 없을 때는 반드시 실질적인final이어야 한다.
람다 공식에서 이 공식을 둘러싼 방법의 국부 변수에 접근할 수 있다.
(람다식으로 전환하기 전의 일을 고려한다면 바로 이런 느낌이다.)
아래와 같이 람다식 내에서 성명식 방법의 국부 변수에 접근할 수 있다.
'실질적으로final'은final에 수식되지 않아도 변경되지 않는 변수를 가리킨다.
아래와 같이 람다식 내에서 국부 변수의 값을 변경하면 컴파일 오류가 발생합니다.
public class Sample {
    public static void main(String[] args) {
        String a = "sample";
        Function f = () -> {
            a = "change"; // エラー
            System.out.println(a);
        };
        // 略
    }
}

java.util.함수 패키지 및 수집 API


빈번하게 사용되는 함수형 인터페이스는 자바입니다.util.function 패키지에서
특히 유명한 곳은 아래 5개의 함수형 인터페이스다.
함수형 인터페이스
방법
매개 변수
반환값
설명
Consumer
void accept(T)
작업 공간의 가장자리에서
하계
값을 반환하지 않는 소비자
Supplier
T get()
하계
작업 공간의 가장자리에서
반환값 공급업체
Predicate
boolean test(T)
작업 공간의 가장자리에서
작업 공간의 가장자리에서
진위 값으로 돌아가는 "단정"
Function
R apply(T)
작업 공간의 가장자리에서
작업 공간의 가장자리에서
매개변수를 적용하고 지정된 유형의 결과를 반환합니다.
UnaryOperator
T apply(T t)
두 개 있다
작업 공간의 가장자리에서
연산 결과를 되돌리는 작업
Collection API에는 List 및 Map을 조작하는 기본 방법이 많이 있습니다.
예를 들어 자바.util.목록에 removeIf(Predicate filter) 방법이 있습니다. filter와 일치하는 요소를 삭제합니다.
람다식을 사용하면 한 줄이면 돼요.
RemoveIf.java
import java.util.ArrayList;
import java.util.Arrays;

public class RemoveIf {
    public static void main(String[] args) {

        ArrayList<String> list = new ArrayList<String>(Arrays.asList("aaaa", "bbb", "cc"));

        list.removeIf(v -> v.length() > 3);

        System.out.println(list); // 結果: [bbb, cc]
    }
}
람다식을 지정할 수 있는 방법도 많이 준비되어 있다.
각자 조사해서 람다식 설치 습관을 사용하세요.

결말


서버 쪽에서 Java8에서 실행되는 WEB 응용 프로그램은 매우 많다.
따라서 저는 현재 자바를 할 때 람다식 & Stream API는 피할 수 없는 지식이라고 생각합니다.
그럼에도 불구하고 자바 신인 연수에서 배울 수 없는 점이 있습니다.
신인을 위해서 가능한 한 간단명료하게 정리해 봤습니다. 이해하기 어려운 부분이 있다면 죄송합니다.
다음에는 다음 주 정도에 Stream API 입문을 요약하고 싶습니다.
(2019.12.22 업데이트) 속편 Something → Java 스트림 API 시작

좋은 웹페이지 즐겨찾기