람다 소개
Lambda Expressions는 Java SE 8에서 중요한 새로운 기능입니다. Lambda Expressions는 기능적 인터페이스를 표현으로 바꿀 수 있습니다. Lambda 표현식은 방법과 같습니다.이 방법은 일반 매개 변수 목록과 본문 (신체, 표현식 또는 코드 블록이 될 수있는 신체 또는 코드 블록)을 제공합니다.
Lambda Expressions는 또한 컬렉션 라이브러리를 향상시킵니다. Java SE 8은 수집 데이터에서 배치 작업을 작동하는 2 개의 패키지를 추가합니다 : java.util.function 패키지 및 java.util.stream 패키지. 스트림은 반복자와 같지만 많은 추가 기능이 첨부되어 있습니다. 일반적으로 Lambda 표현과 스트림은 Java 언어가 제네릭과 주석을 추가하기 때문에 가장 큰 변화입니다.
Lambda 표현식은 본질적으로 익명의 방법이며, 그 기본 계층은 익명 클래스를 생성하기 위해 invokedynamic 지침을 통해 구현됩니다. 더 간단한 구문 및 쓰기 방법을 제공하여 기능 인터페이스를 표현식으로 바꿀 수 있습니다. 일부 사람들의 눈에는 Lambda가 코드를 더 간결하게 만들고 전혀 사용하지 않을 수 있습니다.이 견해는 확실히 괜찮습니다. 그러나 중요한 것은 Lambda가 Java에 폐쇄된다는 것입니다. Lamdba의 컬렉션 지원 덕분에 Lambda는 멀티 코어 프로세서 조건에서 수집을 가로 질러 성능을 향상 시켰습니다. 또한 데이터 스트림 형태로 컬렉션을 처리 할 수 있습니다. 이는 매우 매력적입니다.
람다 구문
Lambda의 구문은 다음 구조와 유사하며 매우 간단합니다.
(매개 변수) -> 표현식
또는
(매개 변수) -> {문; }람다 표현식은 세 부분으로 구성됩니다.
1. 매개 변수 : 유사한 방법의 공식 매개 변수 목록, 여기의 매개 변수는 기능 인터페이스의 매개 변수입니다. 여기서 매개 변수 유형은 명시 적으로 선언되거나 선언되지 않지만 JVM에 의해 암시 적으로 추론 될 수 있습니다. 또한, 추론 유형이 하나만 있으면 괄호를 생략 할 수 있습니다.
2.-> : "사용되는"것으로 이해 될 수 있습니다.
3. 방법 본문 : 표현식 또는 코드 블록 일 수 있으며 기능 인터페이스에서 메소드를 구현하는 것입니다. 코드 블록은 값이나 반전을 반환 할 수 없습니다. 여기의 코드 블록은 메소드의 메소드 본문과 동일합니다. 표현이라면 값을 반환하거나 아무것도 반환 할 수도 있습니다.
다음 예제를 사용하여 다음을 설명하겠습니다.
// 예제 1 : 매개 변수를 수락 할 필요가없고, 직접 반환 할 필요가없고, 10 ()-> 10 // 예제 2 : int 유형의 두 매개 변수를 수락 하고이 두 매개 변수의 합을 반환하고 (int x, int y)-> x+y; // 예제 2 : x와 y의 두 매개 변수를 받아 들여,이 매개 변수의 유형은 컨텍스트를 기반으로 JVM에 의해 추론되며, 두 매개 변수 (x) (x, y)의 두 매개 변수를 반환합니다. 3 : 문자열을 수락하고 문자열을 인쇄하고 컨트롤을 인쇄하고 결과 (문자열 이름)-> system.out.println (name); // 예제 4 : 추론 된 유형 매개 변수 이름을 수락하고 문자열을 콘솔 이름-> system.out.println (이름)에 인쇄하고 두 문자열 타이어 매개 변수를 별도로 수락하고 reatse verse (string, string, string, string). sex)-> {system.out.println (name); system.out.println (sex)} // 예제 6 : 매개 변수 x를 수락하고 매개 변수 x-> 2*x를 두 번 반환합니다.람다를 사용하는 곳
[기능 인터페이스] [1]에서 우리는 Lambda 표현의 목표 유형이 기능적 인터페이스라는 것을 알고 있습니다. 각 Lambda는 특정 기능 인터페이스를 통해 주어진 유형과 일치 할 수 있습니다. 따라서 Lambda 표현은 대상 유형과 일치하는 모든 곳에 적용될 수 있습니다. LAMBDA 표현식은 기능 인터페이스의 추상 함수 설명과 동일한 매개 변수 유형을 가져야하며, 반환 유형은 추상 기능의 리턴 유형과 호환되어야하며, 방지 할 수있는 예외는 함수 설명 범위로 제한됩니다.
다음으로 사용자 정의 기능 인터페이스 예를 살펴 보겠습니다.
@FunctionalInterface 인터페이스 변환기 <f, t> {t convert (f from);}먼저 전통적인 방식으로 인터페이스를 사용하십시오.
Converter <String, Integer> converter = new Converter <String, integer> () {@override public integer convert (string) {return integer.valueof (from); }}; 정수 결과 = converter.convert ( "200"); System.out.println (결과);분명히 이것에 문제가 없으므로 다음은 Lambda를 사용하여 Lambda를 사용하여 컨버터 인터페이스를 구현하는 순간입니다.
변환기 <문자열, 정수> 변환기 = (param) -> integer.valueof (param); 정수 결과 = converter.convert ( "101"); System.out.println (결과);
위의 예를 통해 Lambda 사용에 대한 간단한 이해가 있다고 생각합니다. 아래에서 우리는 일반적으로 사용되는 런 가능한 것을 사용하여 다음을 시연하고 있습니다.
과거에는이 코드를 작성했을 수도 있습니다.
새 스레드 (new Runnable () {@override public void run () {System.out.println ( "Hello Lambda");}}). start ();경우에 따라 많은 익명의 클래스가 코드를 혼란스럽게 보이게 할 수 있습니다. 이제 Lambda를 사용하여 간단하게 만들 수 있습니다.
새 스레드 (() -> system.out.println ( "Hello Lambda")). start ();
메소드 참조
메소드 참조는 Lambda 표현식을 작성하는 단순화 된 방법입니다. 참조 된 방법은 실제로 Lambda 표현의 방법 본문의 구현이며, 구문 구조는 다음과 같습니다.
objectref :: MethodName
왼쪽은 클래스 이름 또는 인스턴스 이름 일 수 있고 중간은 메소드 참조 기호 "::"이며 오른쪽은 해당 메소드 이름입니다.
메소드 참조는 세 가지 범주로 나뉩니다.
1. 정적 메소드 참조
경우에 따라 다음과 같은 코드를 쓸 수도 있습니다.
public class referenceTest {public static void main (string [] args) {converter <string, integer> converter = new converter <string, integer> () {@override public integer convert (string) {return referenceTest.string2int (from); }}; Converter.convert ( "120"); } @functionalInterface 인터페이스 변환기 <f, t> {t convert (f from); } static int string2int (string from) {return integer.valueof (from); }}현재 정적 참조를 사용하면 코드가 더 간결합니다.
Converter <String, Integer> converter = referenceTest :: string2int; Converter.convert ( "120");
2. 인스턴스 메소드 참조
우리는 다음과 같은 코드를 쓸 수도 있습니다.
public class referenceTest {public static void main (string [] args) {converter <string, integer> converter = new converter <string, integer> () {@override public integer convert (string) {return new Helper (). String2int (from); }}; Converter.convert ( "120"); } @functionalInterface 인터페이스 변환기 <f, t> {t convert (f from); } 정적 클래스 도우미 {public int string2int (문자열) {return integer.valueof (from); }}}또한 예제 방법을 사용하여 참조 할 수 있습니다.
도우미 도우미 = 새로운 도우미 (); Converter <String, Integer> Converter = 헬퍼 :: string2int; Converter.convert ( "120");
3. 생성자 메소드 참조
이제 생성자에 대한 참조를 시연합시다. 먼저 부모 수업 동물을 정의합니다.
클래스 동물 {개인 문자열 이름; 사적인 int 연령; 공개 동물 (문자열 이름, int age) {this.name = 이름; this.age = age; } public void behavior () {}} 다음으로, 우리는 동물의 두 가지 서브 클래스를 정의하고 있습니다 : Dog、Bird
공개 계급 새는 동물을 확장합니다. } @override public void zove () {System.out.println ( "fly"); }} Class Dog Extends Animal {public dog (문자열 이름, int Age) {Super (이름, 나이); } @override public void zove () {System.out.println ( "run"); }}그런 다음 공장 인터페이스를 정의합니다.
인터페이스 팩토리 <t는 동물> {t create (문자열 이름, int age); }다음으로, 우리는 전통적인 방법을 사용하여 개와 새 수업의 대상을 만듭니다.
Factory Factory = New Factory () {@override public Animal Create (문자열 이름, int age) {return new Dog (이름, 나이); }}; Factory.create ( "Alias", 3); Factory = New Factory () {@override public Animal Create (String Name, Int Age) {return new Bird (이름, 나이); }}; Factory.create ( "Smook", 2);나는 단지 두 개의 객체를 만들기 위해 10 개 이상의 코드를 썼습니다. 이제 생성자 참조를 사용해 보겠습니다.
공장 <Amenti> dogfactory = dog :: new; Animal Dog = dogfactory.create ( "alias", 4); 공장 <Bird> BirdFactory = Bird :: New; Bird Bird = birdfactory.create ( "smook", 3);
이렇게하면 코드가 깨끗하고 깔끔해 보입니다. Dog::new 사용할 때, Factory.create 서명하여 해당 생성 기능을 선택하십시오.
Lambda의 도메인 및 액세스 제한
도메인은 범위이며 Lambda 표현식의 매개 변수 목록의 매개 변수는 Lambda 표현식 (도메인)의 범위 내에서 유효합니다. Lambda 표현식에서 외부 변수에 액세스 할 수 있습니다 : 로컬 변수, 클래스 변수 및 정적 변수는 작동 정도가 다릅니다.
로컬 변수에 액세스하십시오
Lambda 표현식 외부의 로컬 변수는 JVM에 의해 최종 유형으로 암시 적으로 컴파일되므로 액세스 할 수는 있지만 수정할 수 없습니다.
public class referenceTest {public static void main (String [] args) {int n = 3; 계산 계산 = param-> {// n = 10; 컴파일 오류 반환 n + param; }; 계산 (10); } @functionalInterface 인터페이스 계산 {int calculate (int value); }}정적 및 멤버 변수에 액세스합니다
Lambda 표현식 내부에서 정적 및 멤버 변수는 읽을 수 있고 쓸 수 있습니다.
public class referenceTest {public int count = 1; 공개 정적 int num = 2; public void test () {계산 계산 = param-> {num = 10; // 정적 변수 count = 3; // 멤버 변수 수정 n + param; }; 계산 (10); } public static void main (String [] args) {} @functionalInterface 인터페이스 계산 {int calculation (int value); }}Lambda는 기능 인터페이스의 기본 메소드에 액세스 할 수 없습니다
Java8은 인터페이스에 기본 키워드 정의를 추가 할 수있는 기본 메소드를 포함하여 인터페이스를 향상시킵니다. 기본 방법에 대한 액세스는 내부적으로 지원되지 않는다는 점에 유의해야합니다.
람다 연습
[기능 인터페이스] [2] 섹션에서, 우리는 많은 기능 인터페이스가 java.util.function 패키지에 내장되어 있으며 이제 일반적으로 사용되는 기능 인터페이스를 설명 할 것입니다.
술어 인터페이스
매개 변수를 입력하고 논리적 판단을위한 많은 기본 방법이 포함 된 Boolean 값을 반환하십시오.
@test public void predicttest () {presctice <string> predict = (s) -> s.length ()> 0; 부울 테스트 = predict.test ( "테스트"); System.out.println ( "문자열 길이는 0보다 큽니다 :" + test); test = predict.test ( ""); System.out.println ( "문자열 길이는 0보다 큽니다 :" + test); 술어 <객체> pre = Objects :: nonull; 객체 ob = null; test = pre.test (ob); System.out.println ( "객체는 비어 있지 않습니다 :" + test); ob = new Object (); test = pre.test (ob); System.out.println ( "객체는 비어 있지 않습니다 :" + test); }기능 인터페이스
매개 변수를 받고 단일 결과를 반환하십시오. 기본 메소드 ( andThen )는 여러 기능을 함께 문자하여 복합 Funtion (입력, 출력) 결과를 형성 할 수 있습니다.
@test public void functiontest () {function <string, integer> tointeger = integer :: valueof; // TOINTEGER의 실행 결과는 두 번째 백토 스트링 함수에 대한 입력으로 사용됩니다. <String, String> backtostring = ToInteger.andthen (String :: valueOf); 문자열 결과 = backtostring.apply ( "1234"); System.out.println (결과); 함수 <integer, integer> add = (i) -> {system.out.println ( "frist input :" + i); 반환 i * 2; }; 함수 <integer, integer> Zero = add.andthen ((i) -> {System.out.println ( "두 번째 입력 :" + i); return i * 0;}); 정수 res = Zero.Apply (8); System.out.println (Res); }공급 업체 인터페이스
주어진 유형의 결과를 반환합니다. Function 과 달리 Supplier 매개 변수를 허용 할 필요가 없습니다 (공급 업체, 출력이 있지만 입력이 없습니다)
@test public void suppliertest () {supplier <string> supplier = () -> "특별 유형 값"; 문자열 s = supplier.get (); System.out.println (s); }소비자 인터페이스
단일 입력 매개 변수에서 수행 해야하는 작업을 나타냅니다. Function 과 달리 Consumer 가치를 반환하지 않습니다 (소비자, 입력, 출력 없음)
@test public void consumertest () {소비자 <integer> add5 = (p) -> {system.out.println ( "Old Value :" + P); p = p + 5; System.out.println ( "새 값 :" + P); }; add5.cept (10); } 위의 4 개의 인터페이스의 사용은 java.util.function 패키지의 네 가지 유형을 나타냅니다. 이 네 가지 기능적 인터페이스를 이해 한 후에는 다른 인터페이스를 이해하기 쉽습니다. 이제 간단한 요약을하겠습니다.
Predicate 논리적 판단에 사용되며, Function 입력 및 출력이있는 곳에서 사용되며, Supplier 입력 및 출력이없는 장소에서 사용되며 Consumer 입력이 있고 출력이없는 장소에서 사용됩니다. 이름의 의미에 따라 사용 시나리오를 알 수 있습니다.
개울
Lambda는 컬렉션 작업에서 특히 중요한 Java 8의 폐쇄를 제공합니다. Java 8은 수집 개체의 스트림에서 기능적 작업을 지원합니다. 또한 스트림 API는 컬렉션 API에 통합되어 수집 객체에서 배치 작업을 허용합니다.
스트림을 알아 보겠습니다.
스트림은 데이터 스트림을 나타냅니다. 데이터 구조가 없으며 요소 자체를 저장하지 않습니다. 작업은 소스 스트림을 변경하지 않고 새 스트림을 생성합니다. 작동 데이터를위한 인터페이스로서 필터링, 정렬, 매핑 및 규정을 제공합니다. 이 방법은 리턴 유형에 따라 두 가지 범주로 나뉩니다. 스트림 유형을 반환하는 모든 방법을 중간 방법 (중간 작업)이라고하며 나머지는 완료 방법 (완전 작동)입니다. 완료 방법은 일부 유형의 값을 반환하고 중간 메소드는 새 스트림을 반환합니다. 중간 방법의 호출은 일반적으로 묶여 있으며 프로세스는 파이프 라인을 형성합니다. 최종 방법이 호출되면 파이프 라인에서 즉시 값을 소비하게됩니다. 여기서 우리는 다음을 기억해야합니다. 스트림 작업은 가능한 한 "지연된"것으로 실행됩니다. 이는 자주 "게으른 작업"이라고 부르는 것입니다. 이는 자원 사용을 줄이고 성능을 향상시키는 데 도움이됩니다. 모든 중간 작업 (정렬 제외)의 경우 지연 모드에서 실행됩니다.
스트림은 강력한 데이터 운영 기능을 제공 할뿐만 아니라 더 중요한 것은 직렬 및 병렬 처리를 모두 지원합니다. 병렬 처리를 통해 스트림은 멀티 코어 프로세서에서 더 나은 성능을 발휘할 수 있습니다.
스트림의 사용 프로세스에는 고정 된 패턴이 있습니다.
1. 스트림을 만듭니다
2. 중간 작업을 통해 원래 스트림을 "변경"하고 새 스트림을 생성합니다.
3. 완료 작업을 사용하여 최종 결과를 생성하십시오.
그게
작성 -> 변경 -> 완료
스트림 생성
컬렉션의 경우 Collection의 stream() 또는 parallelStream() 호출하여 만들 수 있습니다. 또한이 두 가지 방법은 컬렉션 인터페이스에서도 구현됩니다. 배열의 경우 스트림의 정적 방법 of(T … values) 에 의해 만들 수 있습니다. 또한 배열은 스트림을 지원합니다.
위의 컬렉션 또는 배열을 기반으로 하천을 작성하는 것 외에도 Steam.empty() 를 통해 빈 스트림을 만들거나 스트림의 generate() 사용하여 무한 스트림을 생성 할 수도 있습니다.
일반적으로 사용되는 몇 가지 중간 및 완성 방법을 설명하기 위해 직렬 스트림을 예로 들어 봅시다. 먼저 목록 수집을 만듭니다.
List <string> lists = new ArrayList <string> (); lists.add ( "a1"); lists.add ( "a2"); lists.add ( "b1"); lists.add ( "b2"); lists.add ( "b3"); lists.add ( "O1");
중간 방법
필터
술어 인터페이스와 결합하여 필터는 스트리밍 객체의 모든 요소를 필터링합니다. 이 작업은 중간 작업이므로 작업에서 반환 한 결과를 기반으로 다른 작업을 수행 할 수 있습니다.
public static void streamfiltertest () {lists.stream (). 필터 ((s-> s.startswith ( "a")). foreach (system.out :: println); // 위의 작업과 동일합니다. PRECTICE <String> PRECTICE = (S) -> S.startSwith ( "A"); lists.stream (). filter (precticate) .foreach (system.out :: println); // 연속 필터링 술어 <String> PRECTICE1 = (S-> S.EndSwith ( "1")); lists.stream (). filter (presctice) .filter (prescticate1) .foreach (system.out :: println); }정렬 (정렬)
비교기 인터페이스와 결합 하여이 작업은 정렬 된 스트림의보기를 반환하며 원래 스트림의 순서는 변경되지 않습니다. Collation 규칙은 비교기를 통해 지정되며 기본값은 자연 순서로 정렬하는 것입니다.
public static void StreamSortedTest () {System.out.println ( "기본 비교기"); lists.stream (). sorted (). 필터 ((s-> s.startswith ( "a")). foreach (system.out :: println); System.out.println ( "Custom Comparator"); lists.stream (). sorted ((p1, p2) -> p2.compareto (p1)). 필터 ((s-> s.startswith ( "a"))). foreach (system.out :: println); }지도 (지도)
Function 인터페이스와 결합 하여이 작업은 스트림 객체의 각 요소를 다른 요소에 매핑하여 요소 유형 변환을 실현할 수 있습니다.
public static void streammaptest () {lists.stream (). map (String :: touppercase) .sorted ((a, b) -> b.compareto (a)). foreach (system.out :: println); System.out.println ( "사용자 정의 매핑 규칙"); function <string, String> function = (p) -> {return p + ".txt"; }; lists.stream (). map (string :: touppercase) .map (function) .sorted ((a, b) -> b.compareto (a)). foreach (system.out :: println); }위의 내용은 일반적으로 사용되는 세 가지 작업을 간략하게 소개하여 컬렉션의 처리를 크게 단순화합니다. 다음으로 완료하는 몇 가지 방법을 소개합니다.
마무리 방법
"변환"프로세스 후에 결과를 얻어야합니다. 즉, 작업이 완료됩니다. 아래의 관련 작업을 살펴 보겠습니다.
성냥
predicate 스트림 객체와 일치하는지 여부를 결정하고 마지막으로 Boolean 유형 결과를 반환합니다.
public static void StreamMatchTest () {// 스트림 객체의 하나의 요소가 부울 anystartwitha = lists.stream (). AnyMatch ((s-> s.startSwith ( "a"))); System.out.println (anystartwitha); // 스트림 객체의 각 요소가 부울 AllStartWitHa = lists.stream (). AllMatch ((s-> s.startSwith ( "a"))); System.out.println (allstartwitha); }모으다
변형 후, 우리는 이러한 요소를 컬렉션에 저장하는 것과 같은 변환 된 스트림의 요소를 수집합니다. 현재 스트림에서 제공하는 수집 방법을 예를 들어 사용할 수 있습니다.
public static void StreamCollectTest () {list <string> list = lists.stream (). filter ((p) -> p.startswith ( "a")). sorted (). collect (collectors.tolist ()); System.out.println (목록); }세다
SQL 유사 카운트는 스트림의 총 요소 수를 계산하는 데 사용됩니다.
public static void StreamCountTest () {long count = lists.stream (). 필터 ((s-> s.startswith ( "a")). count (); System.out.println (count); }줄이다
reduce 방법을 통해 우리는 자체 방식으로 요소를 계산하거나 스트림의 요소를 예를 들어 패턴으로 계산할 수 있습니다.
public static void StreamEducetest () {옵션 <string> 옵션 = lists.stream (). sorted (). reture ((s1, s2) -> {system.out.println (s1 + "|" + s2); return s1 + "|" + s2;}); }실행 결과는 다음과 같습니다.
a1 | a2a1 | a2 | b1a1 | a2 | b1 | b2a1 | a2 | b1 | b2 | b3a1 | a2 | b1 | b2 | b3 | o1
병렬 스트림 대 직렬 스트림
지금까지 우리는 일반적으로 사용되는 중간 및 완성 된 작업을 도입했습니다. 물론 모든 예제는 직렬 스트림을 기반으로합니다. 다음으로, 우리는 주요 드라마 - 병렬 스트림 (병렬 스트림)을 소개합니다. 병렬 스트림은 포크 조인 병렬 분해 프레임 워크를 기반으로 구현되며 빅 데이터 세트를 여러 개의 작은 데이터로 나누고 처리를 위해 다른 스레드로 넘겨줍니다. 이러한 방식으로, 멀티 코어 처리 상황에서 성능이 크게 향상 될 것입니다. 이는 MapReduce의 설계 개념과 일치합니다. 대규모 작업이 작아지고 작은 작업이 다른 기계에 실행을 위해 재 할당됩니다. 그러나 여기서 작은 작업은 다른 프로세서에 전달됩니다.
parallelStream() 을 통해 병렬 스트림을 만듭니다. 병렬 스트림이 성능을 실제로 향상시킬 수 있는지 확인하기 위해 다음 테스트 코드를 실행합니다.
먼저 더 큰 컬렉션을 만듭니다.
<string> biglists = new ArrayList <> (); for (int i = 0; i <100000000; i ++) {uuid uuid = uuid.randomuuid (); biglists.add (uuid.tostring ()); }직렬 스트림에서 정렬 할 시간을 테스트하십시오.
개인 정적 void notparallelstreamsortedTest (list <string> biglists) {long starttime = system.nanotime (); long count = biglists.stream (). sorted (). count (); Long Endtime = System.NanoTime (); long millis = timeUnit.nanoseconds.tomillis (endtime -starttime); System.out.println (System.out.printf ( "Serial Sort : %D MS", Millis)); }병렬 스트림으로 정렬하는 시간을 테스트하십시오.
개인 정적 void allelStreamSortedTest (list <string> biglists) {long starttime = system.nanoTime (); long count = biglists.parallelstream (). sorted (). count (); Long Endtime = System.NanoTime (); long millis = timeUnit.nanoseconds.tomillis (endtime -starttime); System.out.println (System.out.printf ( "ParallelSorting : %D MS", Millis)); }결과는 다음과 같습니다.
일련 정렬 : 13336ms
평행 정렬 : 6755ms
이것을 본 후, 우리는 성능이 약 50%향상되었음을 발견했습니다. 또한 앞으로 parallel Stream 사용할 수 있다고 생각하십니까? 실제로는 그렇지 않습니다. 아직 단일 코어 프로세서이고 데이터 볼륨이 크지 않다면 직렬 스트리밍은 여전히 좋은 선택입니다. 또한 어떤 경우에는 직렬 스트림의 성능이 더 좋습니다. 특정 사용은 먼저 테스트 한 다음 실제 시나리오에 따라 결정해야합니다.
게으른 수술
위에서 우리는 가능한 한 늦게 실행되는 스트림에 대해 이야기했으며 여기서는 무한한 스트림을 만들어 설명합니다.
먼저 스트림 generate 메소드를 사용하여 자연 숫자 시퀀스를 생성 한 다음 map 통해 스트림을 변환합니다.
// 증분 시퀀스 클래스 Class Natureseq 공급 업체 <long> {long value = 0; @override public long get () {value ++; 반환 값; }} public void StreamCreateStest () {stream <long> stream = stream.generate (new Natureseq ()); System.out.println ( "요소 수 :"+stream.map ((param) -> {return param;}). limit (1000) .count ()); }실행 결과는 다음과 같습니다.
요소 수 : 1000
처음에는 중간 작업 ( filter,map 등과 같은 중간 작업이지만 sorted 할 수 없음)은 괜찮다는 것을 알았습니다. 즉, 스트림에서 중간 작업을 수행하고 새로운 스트림에서 생존하는 프로세스는 즉시 적용되지 않습니다 (또는이 예제의 map 작업은 영원히 실행되어 차단됩니다). 스트림은 완료 방법이 발생할 때 계산을 시작합니다. limit() 메소드를 통해이 무한 스트림을 유한 스트림으로 변환하십시오.
요약
위의 것은 Java Lambda에 대한 빠른 소개의 모든 내용입니다. 이 기사를 읽은 후 Java Lambda에 대한 더 깊은 이해가 있습니까? 이 기사가 모든 사람이 Java Lambda를 배우는 데 도움이되기를 바랍니다.