Lambda 표현식에 처음 노출 된 것은 TypeScript (JavaScript의 슈퍼 세트)에 있었고이 방법이 아닌이 방법을 벗어난 TypeScript의 방법을 만들기위한 것이 었습니다. 그것을 사용한 후, 나는 람다가 JDK8의 헤비급 새로운 기능이 아니라는 것을 갑자기 깨달았습니다. 그래서 나는 관련 정보를 확인하고 그것을 기록했다고 생각했습니다.
1. 행동 매개 변수화
요컨대, 동작 매개 변수화는 함수의 본문에 템플릿과 유사한 일반 코드 만 포함되며 비즈니스 시나리오로 변경되는 일부 논리는 매개 변수 형태로 함수로 전달됩니다. 행동 매개 변수화를 사용하면 프로그램이 더 일반적인 변화의 요구에 대처할 수 있습니다.
프로그램을 통해 Apple을 필터링해야한다고 가정하면 Apple 엔티티를 먼저 정의하는 비즈니스 시나리오를 고려하십시오.
공개 클래스 Apple {/** 숫자*/private long id;/** color*/private color color;/** weight*/private float weight;/private float weight;/** origin*/private string origin; public apple () {} public Apple (Long ID, Color Color, Float Weign, String Origin) {this.id = id; this.color = color; this.weight = weight; this.origin;사용자의 초기 요구는 단순히 프로그램을 통해 녹색 사과를 걸러내는 것일 수 있으므로 프로그램을 통해 신속하게 구현할 수 있습니다.
public static list <ply> filtergreenapples (list <ply> 사과) {list <plect <plect> filterapples = new arraylist <> (); for (Final Apple : Apples) {if (color.green.equals (apple.getColor ())) {filterapples.Add (Apple);}} returapples;}이 코드는 간단하고 말할 가치가 없습니다. 그러나 사용자가 녹색이 필요할 때 코드를 수정하는 것이 간단한 것 같습니다. 판단 조건의 녹색을 빨간색으로 바꾸는 것 이상입니다. 그러나 우리는 또 다른 문제를 고려해야합니다. 변화 조건이 자주 변하면이 작업이 완료됩니까? 색상 변화 일 경우, 사용자가 색상 판단 조건에서 직접 통과하고 판단 방법의 매개 변수가 "판단 될 세트와 필터링 될 색상"을 변경할 수 있습니다. 그러나 사용자가 색상을 판단 할뿐만 아니라 체중, 크기 등을 판단하려면 어떻게해야합니까? 판단을 완료하기 위해 다른 매개 변수를 추가 할 수 있다고 생각하십니까? 그러나 이와 같은 매개 변수를 전달하는 것이 정말 좋은가요? 더 많은 필터링 조건이 있고 조합 모드가 점점 더 복잡해지면 모든 상황을 고려하고 각 상황에 대한 대처 전략이 있어야합니까? 이 시점에서는 동작을 매개 변수화하고 필터링 조건을 추출하여 매개 변수로 전달할 수 있습니다. 현재 판단 인터페이스를 캡슐화 할 수 있습니다.
public interface applefilter {/*** 필터 초록 ** @param apple* @return*/boolean accept (Apple Apple);}/*** 인터페이스에 필터를 캡슐화 ** @param 사과*@param 필터* @return*/public static list <plect> filterapplesbyApplefilter (list <plect> 사과, Applefilter) ArrayList <> (); for (Final Apple Apple : Apples) {if (filter.accept (Apple)) {filterapples.add (Apple);}} 필터 랩플 리턴;}위의 동작 추상화 후, 우리는 특정 호출에서 필터 조건을 설정하고 조건을 메소드로 매개 변수로 전달할 수 있습니다. 현재 우리는 익명의 내부 클래스 방법을 사용합니다.
public static void main (string [] args) {list <plect <plect <plect <> (); // 필터 애플리스트 <plect> 필터 apples = filterapplesbyApplefilter (사과, 새로운 applefilter () {@overridepublic boolean accept (Apple Apple) {// weight weight weight.) apple.getweight ()> 100;}});}이 디자인은 java.util.comparator, java.util.concurrent.callable 등과 같은 JDK 내에서 종종 사용됩니다.이 유형의 인터페이스를 사용할 때 익명 클래스를 사용하여 특정 통화 위치에서 기능의 특정 실행 논리를 지정할 수 있습니다. 그러나 위의 코드 블록에서는 매우 괴짜이지만 간결하지는 않습니다. Java8에서는 Lambda를 통해 단순화 할 수 있습니다.
// filter Apple List <Plece> filterApples = FilterApplesByAppLeFilter (Apples, (Apple) -> color.red.quals (apple.getColor ()) && apple.getweight ()> = 100); // () -> xxx ()는 메소드 매개 변수이며 메소드 구현입니다.
2. 람다 표현 정의
우리는 Lambda 표현을 간결하고 통과 가능한 익명 기능으로 정의 할 수 있습니다. 우선, 우리는 Lambda 표현이 본질적으로 함수임을 분명히해야합니다. 특정 클래스에 속하지는 않지만 매개 변수 목록, 기능 본문, 반환 유형 및 예외를 던지는 능력이 있습니다. 둘째, 그것은 익명이며 Lambda 표현에는 특정 기능 이름이 없습니다. Lambda 표현식은 매개 변수처럼 전달 될 수 있으므로 코드 작성을 크게 단순화합니다. 형식 정의는 다음과 같습니다.
형식 1 : 매개 변수 목록 -> 표현식
형식 2 : 매개 변수 목록 -> {expression collection}
Lambda 표현식은 반환 키워드를 암시하므로 단일 표현식에서는 반환 키워드를 명시 적으로 작성할 필요가 없지만 표현식이 명세서 모음 일 때는 명시 적으로 반환을 추가하고 Curly Braces {}로 여러 표현식을 둘러싸고 있습니다. 아래 몇 가지 예를 보겠습니다.
// 주어진 문자열의 길이를 반환하고, 암시 적으로 return 문 (string s) -> s.length () // 항상 논쟁의 여지가없는 메소드를 반환합니다 () -> 42 // 곱슬 괄호 (int x, int y) -> {int z = x * y; return x + z;}에 포함되어 있습니다.3. 기능적 인터페이스를 기반으로 Lambda 표현식을 사용하십시오
Lambda 표현식을 사용하려면 기능 인터페이스의 도움이 필요합니다. 즉, 기능 인터페이스가 나타날 때만 Lambda 표현식으로 단순화 할 수 있습니다.
사용자 정의 기능 인터페이스 :
기능적 인터페이스는 하나의 추상 방법 만있는 인터페이스로 정의됩니다. Java8의 인터페이스 정의 개선은 기본 메소드를 도입하여 인터페이스에서 메소드의 기본 구현을 제공 할 수 있도록하는 것입니다. 그러나, 하나의 기본 메소드가 존재하는지에 관계없이 하나의 추상 방법 만있는 한 다음과 같이 기능 인터페이스입니다 (위의 AppleFilter 참조).
/*** Apple 필터 인터페이스*/ @functionalInterFacePublic Interface AppleFilter {/*** 필터 조건 초록 ** @Param Apple* @return*/boolean accept (Apple Apple);}AppleFilter에는 추상 방법 수락 (Apple Apple) 만 포함되어 있습니다. 정의에 따르면 기능 인터페이스로 간주 될 수 있습니다. 정의 할 때 인터페이스를 함수 인터페이스로 표시하기 위해 @functionalInterface 주석을 인터페이스에 추가합니다. 그러나이 인터페이스는 선택 사항입니다. 이 인터페이스를 추가 한 후 컴파일러는 인터페이스를 추상적 인 메소드 만 갖도록 제한하면 오류 가보고 되므로이 주석을 기능 인터페이스에 추가하는 것이 좋습니다.
JDK는 기능 인터페이스와 함께 제공됩니다.
JDK는 풍부한 기능적 인터페이스를 가진 람다 표현입니다. 아래는 술어 <t>, 소비자 <t>, 함수 <t, r>의 사용의 예입니다.
술부:
@FunctionalInterFacePublic interface precte <t> {/*** 주어진 인수에 대해이 예측을 평가합니다. ** @param t 입력 인수* @return {@code true} 입력 인수가 예측과 일치하는 경우 {@code false}*/boolean test (t t);}.술어의 기능은 위의 AppleFilter와 유사합니다. 수신 매개 변수를 확인하기 위해 외부에서 설정 한 조건을 사용하고 확인 결과 부울을 반환합니다. 다음은 술어를 사용하여 목록 컬렉션의 요소를 필터링합니다.
/**** @param prectice* @param prectice* @param <t>* @return*/public <t> list <t> 필터 (목록 <t> 목록, Predicate <t> prectice) {list <t> presctice) {list <t> prectice = newlist = new arraylist <t> (); for (final t : list) {if (preticate.test (t)) {t);}};사용:
demo.filter (list, (string str) -> null! = str &&! str.isempty ());
소비자
@functionalInterFacePublic 인터페이스 소비자 <t> {/*** 주어진 인수 에서이 작업을 수행합니다. ** @param t 입력 인수*/void acccept (t t);}소비자는 매개 변수를 수신하지만 값을 반환하지 않는 수락 추상 기능을 제공합니다. 다음은 소비자를 사용하여 컬렉션을 통과합니다.
/*** 컬렉션 및 수행 수행의 순회 사용자 정의 동작 ** @Param List* @param 소비자* @param <t>*/public <t> void Filter (list <t> 목록, 소비자 <t> 소비자) {for (final t t : list) {소비자 .accept (t);}}위의 기능 인터페이스를 사용하여 문자열 컬렉션을 반복하고 비어 있지 않은 문자열을 인쇄하십시오.
demo.filter (list, (string str) -> {if (stringutils.isnotblank (str)) {System.out.println (str);}});기능
@functionalInterFacePublic Interface 함수 <t, r> {/***이 함수를 주어진 인수에 적용합니다. ** @param t 함수 인수* @return 함수 결과*/r apply (t t);}함수는 변환 작업을 수행합니다. 입력은 T 형의 데이터이며 유형 R의 데이터를 반환합니다. 다음은 기능을 사용하여 세트를 변환합니다.
public <t, r> list <r> 필터 (List <t> 목록, 함수 <t, r> function) {list <r> newlist = new arraylist <r> (); for (final t t : list) {newlist.add (function.apply (t));} return newlist;}다른:
demo.filter (list, (string str) -> integer.parseint (str));
위의 기능적 인터페이스는 또한 논리적 작업의 일부 기본 구현을 제공합니다. java8 인터페이스의 기본 메소드를 소개 할 때 나중에 이야기합시다 ~
사용 중에주의를 기울여야 할 몇 가지 사항 :
입력 : 추론 :
인코딩 프로세스 중에는 호출 코드가 일치하는 기능 인터페이스가 궁금 할 수도 있습니다. 실제로 컴파일러는 매개 변수, 반환 유형, 예외 유형 (현재) 등을 기준으로 올바른 판단을합니다.
특정 방식으로 호출 할 때 매개 변수 유형을 때때로 생략하여 코드를 더욱 단순화 할 수 있습니다.
// 필터 Apple List <Plece> FilterApples = FilterApplesByAppleFilter (Apples, (Apple) -> color.red.equals (apple.getColor ()) && apple.getweight ()> = 100); // 일부 경우에도 매개 변수 유형을 생략 할 수 있으며, Filterapples = Apples (Filterapples). color.red.equals (apple.getColor ()) && apple.getweight ()> = 100);
로컬 변수
Lambda 표현의 모든 예제는 신체 매개 변수를 사용합니다. 다음과 같이 Lambda의 로컬 변수를 사용할 수도 있습니다.
int weight = 100; list <plecteapples = filterapplesbyAppleFilter (사과, apple-> color.red.quals (apple.getColor ()) && apple.getweight ()> = weight); :
이 예에서는 Lambda에서 로컬 가변 가중치를 사용합니다. 그러나 Lambda에서 로컬 변수를 사용하려면 변수가 최종 또는 실제로 최종적으로 명시 적으로 선언되어야합니다. 이것은 주로 로컬 변수가 스택에 저장되고 Lambda 표현이 다른 스레드에서 실행되기 때문입니다. 스레드보기가 로컬 변수에 액세스하면 변수는 변경 또는 재활용 가능성이 있으므로 최종 수정 후 스레드 안전 문제가 없습니다.
IV. 방법 인용
메소드 참조를 사용하면 코드를보다 단순화 할 수 있습니다. 때때로이 단순화는 코드를보다 직관적으로 보이게 만듭니다. 예를 살펴 보겠습니다.
/* ... 사과의 초기화 작업을 생략* /// Lambda Expression Apples.SORT ((Apple A, Apple B) -> float.compare (a.getweight (), B.getweight ()); // 사과를 참조하여 방법을 사용하여 (비교기 (Apple :: getweight));
메소드 참조 연결 메소드 멤버십 및 메소드 자체를 통해 ::, 주로 세 가지 범주로 나뉩니다.
정적 방법
(args) -> classname.staticMethod (args)
변환
ClassName :: 정적 메드
매개 변수의 예제
(args) -> args.instancemethod ()
변환
className :: Instancemethod // classname은 Args 유형입니다
외부 인스턴스 방법
(args) -> ext.instancemethod (args)
변환
ext :: instancemethod (args)
참조 :
http://www.codeceo.com/article/lambda-of-java-8.html
위는 편집자가 소개 한 새로운 JDK8 기능의 Lambda 표현입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!