国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - 快速入門Java中的Lambda表達式

快速入門Java中的Lambda表達式

2020-06-03 11:54daisy JAVA教程

Lambda作為函數(shù)式編程中的基礎(chǔ)部分,在其他編程語言中早就廣為使用,但在Java領(lǐng)域中發(fā)展較慢,直到j(luò)ava8,才開始支持Lambda。網(wǎng)上關(guān)于Lambda的教程很多,今天小編給大家分享一篇快速入手Lambda的教程。

Lambda簡介

Lambda表達式是Java SE 8中一個重要的新特性。lambda表達式允許你通過表達式來代替功能接口。 lambda表達式就和方法一樣,它提供了一個正常的參數(shù)列表和一個使用這些參數(shù)的主體(body,可以是一個表達式或一個代碼塊)。

Lambda表達式還增強了集合庫。 Java SE 8添加了2個對集合數(shù)據(jù)進行批量操作的包: java.util.function 包以及 java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了許多額外的功能。 總的來說,lambda表達式和 stream 是自Java語言添加泛型(Generics)和注解(annotation)以來最大的變化。

Lambda表達式本質(zhì)上是匿名方法,其底層還是通過invokedynamic指令來生成匿名類來實現(xiàn)。它提供了更為簡單的語法和寫作方式,允許你通過表達式來代替函數(shù)式接口。在一些人看來,Lambda就是可以讓你的代碼變得更簡潔,完全可以不使用——這種看法當然沒問題,但重要的是lambda為Java帶來了閉包。得益于Lamdba對集合的支持,通過Lambda在多核處理器條件下對集合遍歷時的性能提高極大,另外我們可以以數(shù)據(jù)流的方式處理集合——這是非常有吸引力的。

Lambda語法

Lambda的語法極為簡單,類似如下結(jié)構(gòu):

?
1
(parameters) -> expression

或者

?
1
(parameters) -> { statements; }

Lambda表達式由三部分組成:

      1、paramaters:類似方法中的形參列表,這里的參數(shù)是函數(shù)式接口里的參數(shù)。這里的參數(shù)類型可以明確的聲明也可不聲明而由JVM隱含的推斷。另外當只有一個推斷類型時可以省略掉圓括號。

      2、->:可理解為“被用于”的意思

      3、方法體:可以是表達式也可以代碼塊,是函數(shù)式接口里方法的實現(xiàn)。代碼塊可返回一個值或者什么都不反回,這里的代碼塊塊等同于方法的方法體。如果是表達式,也可以返回一個值或者什么都不反回。

我們通過以下幾個示例來做說明:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//示例1:不需要接受參數(shù),直接返回10
()->10
 
//示例2:接受兩個int類型的參數(shù),并返回這兩個參數(shù)相加的和
(int x,int y)->x+y;
 
//示例2:接受x,y兩個參數(shù),該參數(shù)的類型由JVM根據(jù)上下文推斷出來,并返回兩個參數(shù)的和
(x,y)->x+y;
 
//示例3:接受一個字符串,并將該字符串打印到控制到,不反回結(jié)果
(String name)->System.out.println(name);
 
//示例4:接受一個推斷類型的參數(shù)name,并將該字符串打印到控制臺
name->System.out.println(name);
 
//示例5:接受兩個String類型參數(shù),并分別輸出,不反回
(String name,String sex)->{System.out.println(name);System.out.println(sex)}
 
//示例6:接受一個參數(shù)x,并返回該該參數(shù)的兩倍
x->2*x

Lambda用在哪里

在[函數(shù)式接口][1]中我們知道Lambda表達式的目標類型是函數(shù)性接口——每一個Lambda都能通過一個特定的函數(shù)式接口與一個給定的類型進行匹配。因此一個Lambda表達式能被應(yīng)用在與其目標類型匹配的任何地方,lambda表達式必須和函數(shù)式接口的抽象函數(shù)描述一樣的參數(shù)類型,它的返回類型也必須和抽象函數(shù)的返回類型兼容,并且他能拋出的異常也僅限于在函數(shù)的描述范圍中。

接下來,我們看一個自定義的函數(shù)式接口示例:

?
1
2
3
4
5
6
@FunctionalInterface
 interface Converter<F, T>{
 
   T convert(F from);
 
}

首先用傳統(tǒng)的方式來使用該接口:

?
1
2
3
4
5
6
7
8
9
Converter<String ,Integer> converter=new Converter<String, Integer>() {
     @Override
     public Integer convert(String from) {
       return Integer.valueOf(from);
     }
   };
 
   Integer result = converter.convert("200");
   System.out.println(result);

很顯然這沒任何問題,那么接下里就是Lambda上場的時刻,用Lambda實現(xiàn)Converter接口:

?
1
2
3
Converter<String ,Integer> converter=(param) -> Integer.valueOf(param);
    Integer result = converter.convert("101");
    System.out.println(result);

通過上例,我想你已經(jīng)對Lambda的使用有了個簡單的認識,下面,我們在用一個常用的Runnable做演示:

在以前我們可能會寫下這種代碼:

?
1
2
3
4
5
6
new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("hello lambda");
      }
    }).start();

在某些情況下,大量的匿名類會讓代碼顯得雜亂無章。現(xiàn)在可以用Lambda來使它變得簡潔:

?
1
new Thread(() -> System.out.println("hello lambda")).start();

方法引用

方法引用是Lambda表達式的一個簡化寫法。所引用的方法其實是Lambda表達式的方法體的實現(xiàn),其語法結(jié)構(gòu)為:

?
1
ObjectRef::methodName

左邊可以是類名或者實例名,中間是方法引用符號”::”,右邊是相應(yīng)的方法名。

方法引用被分為三類:

1. 靜態(tài)方法引用

在某些情況下,我們可能寫出這樣的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ReferenceTest {
  public static void main(String[] args) {
    Converter<String ,Integer> converter=new Converter<String, Integer>() {
      @Override
      public Integer convert(String from) {
        return ReferenceTest.String2Int(from);
      }
    };
    converter.convert("120");
 
  }
 
  @FunctionalInterface
  interface Converter<F,T>{
    T convert(F from);
  }
 
  static int String2Int(String from) {
    return Integer.valueOf(from);
  }
}

這時候如果用靜態(tài)引用會使的代碼更加簡潔:

?
1
2
Converter<String, Integer> converter = ReferenceTest::String2Int;
converter.convert("120");

2. 實例方法引用

我們也可能會寫下這樣的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ReferenceTest {
  public static void main(String[] args) {
 
    Converter<String, Integer> converter = new Converter<String, Integer>() {
      @Override
      public Integer convert(String from) {
        return new Helper().String2Int(from);
      }
    };
    converter.convert("120");
  }
 
  @FunctionalInterface
  interface Converter<F, T> {
    T convert(F from);
  }
 
  static class Helper {
    public int String2Int(String from) {
      return Integer.valueOf(from);
    }
  }
}

同樣用實例方法引用會顯得更加簡潔:

?
1
2
3
Helper helper = new Helper();
Converter<String, Integer> converter = helper::String2Int;
converter.convert("120");

3. 構(gòu)造方法引用

現(xiàn)在我們來演示構(gòu)造方法的引用。首先我們定義一個父類Animal:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
class Animal{
  private String name;
  private int age;
 
  public Animal(String name, int age) {
    this.name = name;
    this.age = age;
  }
 
  public void behavior(){
 
  }
}

接下來,我們在定義兩個Animal的子類:Dog、Bird

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Bird extends Animal {
 
  public Bird(String name, int age) {
    super(name, age);
  }
 
  @Override
  public void behavior() {
    System.out.println("fly");
  }
}
 
class Dog extends Animal {
 
  public Dog(String name, int age) {
    super(name, age);
  }
 
  @Override
  public void behavior() {
    System.out.println("run");
  }
}

隨后我們定義工廠接口:

?
1
2
3
interface Factory<T extends Animal> {
  T create(String name, int age);
}

接下來我們還是用傳統(tǒng)的方法來創(chuàng)建Dog類和Bird類的對象:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Factory factory=new Factory() {
  @Override
  public Animal create(String name, int age) {
    return new Dog(name,age);
  }
};
factory.create("alias", 3);
factory=new Factory() {
  @Override
  public Animal create(String name, int age) {
    return new Bird(name,age);
  }
};
factory.create("smook", 2);

僅僅為了創(chuàng)建兩個對象就寫了十多號代碼,現(xiàn)在我們用構(gòu)造函數(shù)引用試試:

?
1
2
3
4
5
Factory<Animal> dogFactory =Dog::new;
Animal dog = dogFactory.create("alias", 4);
 
Factory<Bird> birdFactory = Bird::new;
Bird bird = birdFactory.create("smook", 3);

這樣代碼就顯得干凈利落了。通過Dog::new這種方式來穿件對象時,Factory.create函數(shù)的簽名選擇相應(yīng)的造函數(shù)。

Lambda的域以及訪問限制

域即作用域,Lambda表達式中的參數(shù)列表中的參數(shù)在該Lambda表達式范圍內(nèi)(域)有效。在作用Lambda表達式內(nèi),可以訪問外部的變量:局部變量、類變量和靜態(tài)變量,但操作受限程度不一。

訪問局部變量

在Lambda表達式外部的局部變量會被JVM隱式的編譯成final類型,因此只能訪問外而不能修改。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ReferenceTest {
  public static void main(String[] args) {
 
    int n = 3;
    Calculate calculate = param -> {
      //n=10; 編譯錯誤
      return n + param;
    };
    calculate.calculate(10);
  }
 
  @FunctionalInterface
  interface Calculate {
    int calculate(int value);
  }
 
}

訪問靜態(tài)變量和成員變量

在Lambda表達式內(nèi)部,對靜態(tài)變量和成員變量可讀可寫。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ReferenceTest {
  public int count = 1;
  public static int num = 2;
 
  public void test() {
    Calculate calculate = param -> {
      num = 10;//修改靜態(tài)變量
      count = 3;//修改成員變量
      return n + param;
    };
    calculate.calculate(10);
  }
 
  public static void main(String[] args) {
 
  }
 
  @FunctionalInterface
  interface Calculate {
    int calculate(int value);
  }
 
}

Lambda不能訪問函數(shù)接口的默認方法

java8增強了接口,其中包括接口可添加default關(guān)鍵詞定義的默認方法,這里我們需要注意,Lambda表達式內(nèi)部不支持訪問默認方法。

Lambda實踐

在[函數(shù)式接口][2]一節(jié)中,我們提到java.util.function包中內(nèi)置許多函數(shù)式接口,現(xiàn)在將對常用的函數(shù)式接口做說明。

Predicate接口

輸入一個參數(shù),并返回一個Boolean值,其中內(nèi)置許多用于邏輯判斷的默認方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void predicateTest() {
  Predicate<String> predicate = (s) -> s.length() > 0;
  boolean test = predicate.test("test");
  System.out.println("字符串長度大于0:" + test);
 
  test = predicate.test("");
  System.out.println("字符串長度大于0:" + test);
 
  test = predicate.negate().test("");
  System.out.println("字符串長度小于0:" + test);
 
  Predicate<Object> pre = Objects::nonNull;
  Object ob = null;
  test = pre.test(ob);
  System.out.println("對象不為空:" + test);
  ob = new Object();
  test = pre.test(ob);
  System.out.println("對象不為空:" + test);
}

Function接口

接收一個參數(shù),返回單一的結(jié)果,默認的方法(andThen)可將多個函數(shù)串在一起,形成復(fù)合Funtion(有輸入,有輸出)結(jié)果,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void functionTest() {
  Function<String, Integer> toInteger = Integer::valueOf;
  //toInteger的執(zhí)行結(jié)果作為第二個backToString的輸入
  Function<String, String> backToString = toInteger.andThen(String::valueOf);
  String result = backToString.apply("1234");
  System.out.println(result);
 
  Function<Integer, Integer> add = (i) -> {
    System.out.println("frist input:" + i);
    return i * 2;
  };
  Function<Integer, Integer> zero = add.andThen((i) -> {
    System.out.println("second input:" + i);
    return i * 0;
  });
 
  Integer res = zero.apply(8);
  System.out.println(res);
}

Supplier接口

返回一個給定類型的結(jié)果,與Function不同的是,Supplier不需要接受參數(shù)(供應(yīng)者,有輸出無輸入)

?
1
2
3
4
5
6
@Test
public void supplierTest() {
  Supplier<String> supplier = () -> "special type value";
  String s = supplier.get();
  System.out.println(s);
}

Consumer接口

代表了在單一的輸入?yún)?shù)上需要進行的操作。和Function不同的是,Consumer沒有返回值(消費者,有輸入,無輸出)

?
1
2
3
4
5
6
7
8
9
@Test
public void consumerTest() {
  Consumer<Integer> add5 = (p) -> {
    System.out.println("old value:" + p);
    p = p + 5;
    System.out.println("new value:" + p);
  };
  add5.accept(10);
}

以上四個接口的用法代表了java.util.function包中四種類型,理解這四個函數(shù)式接口之后,其他的接口也就容易理解了,現(xiàn)在我們來做一下簡單的總結(jié):

Predicate用來邏輯判斷,Function用在有輸入有輸出的地方,Supplier用在無輸入,有輸出的地方,而Consumer用在有輸入,無輸出的地方。你大可通過其名稱的含義來獲知其使用場景。

Stream

Lambda為java8帶了閉包,這一特性在集合操作中尤為重要:java8中支持對集合對象的stream進行函數(shù)式操作,此外,stream api也被集成進了collection api,允許對集合對象進行批量操作。

下面我們來認識Stream。

Stream表示數(shù)據(jù)流,它沒有數(shù)據(jù)結(jié)構(gòu),本身也不存儲元素,其操作也不會改變源Stream,而是生成新Stream.作為一種操作數(shù)據(jù)的接口,它提供了過濾、排序、映射、規(guī)約等多種操作方法,這些方法按照返回類型被分為兩類:凡是返回Stream類型的方法,稱之為中間方法(中間操作),其余的都是完結(jié)方法(完結(jié)操作)。完結(jié)方法返回一個某種類型的值,而中間方法則返回新的Stream。中間方法的調(diào)用通常是鏈式的,該過程會形成一個管道,當完結(jié)方法被調(diào)用時會導(dǎo)致立即從管道中消費值,這里我們要記住:Stream的操作盡可能以“延遲”的方式運行,也就是我們常說的“懶操作”,這樣有助于減少資源占用,提高性能。對于所有的中間操作(除sorted外)都是運行在延遲模式下。

Stream不但提供了強大的數(shù)據(jù)操作能力,更重要的是Stream既支持串行也支持并行,并行使得Stream在多核處理器上有著更好的性能。

Stream的使用過程有著固定的模式:

      1、創(chuàng)建Stream

      2、通過中間操作,對原始Stream進行“變化”并生成新的Stream

      3、使用完結(jié)操作,生成最終結(jié)果

也就是

      創(chuàng)建——>變化——>完結(jié)

Stream的創(chuàng)建

對于集合來說,可以通過調(diào)用集合的stream()或者parallelStream()來創(chuàng)建,另外這兩個方法也在Collection接口中實現(xiàn)了。對于數(shù)組來說,可以通過Stream的靜態(tài)方法of(T … values)來創(chuàng)建,另外,Arrays也提供了有關(guān)stream的支持。

除了以上基于集合或者數(shù)組來創(chuàng)建Stream,也可以通過Steam.empty()創(chuàng)建空的Stream,或者利用Stream的generate()來創(chuàng)建無窮的Stream。

下面我們以串行Stream為例,分別說明Stream幾種常用的中間方法和完結(jié)方法。首先創(chuàng)建一個List集合:

?
1
2
3
4
5
6
7
List<String> lists=new ArrayList<String >();
    lists.add("a1");
    lists.add("a2");
    lists.add("b1");
    lists.add("b2");
    lists.add("b3");
    lists.add("o1");

中間方法

過濾器(Filter)

結(jié)合Predicate接口,F(xiàn)ilter對流對象中的所有元素進行過濾,該操作是一個中間操作,這意味著你可以在操作返回結(jié)果的基礎(chǔ)上進行其他操作。

?
1
2
3
4
5
6
7
8
9
10
11
public static void streamFilterTest() {
  lists.stream().filter((s -> s.startsWith("a"))).forEach(System.out::println);
 
  //等價于以上操作
  Predicate<String> predicate = (s) -> s.startsWith("a");
  lists.stream().filter(predicate).forEach(System.out::println);
 
  //連續(xù)過濾
  Predicate<String> predicate1 = (s -> s.endsWith("1"));
  lists.stream().filter(predicate).filter(predicate1).forEach(System.out::println);
}

排序(Sorted)

結(jié)合Comparator接口,該操作返回一個排序過后的流的視圖,原始流的順序不會改變。通過Comparator來指定排序規(guī)則,默認是按照自然順序排序。

?
1
2
3
4
5
6
7
8
public static void streamSortedTest() {
  System.out.println("默認Comparator");
  lists.stream().sorted().filter((s -> s.startsWith("a"))).forEach(System.out::println);
 
  System.out.println("自定義Comparator");
  lists.stream().sorted((p1, p2) -> p2.compareTo(p1)).filter((s -> s.startsWith("a"))).forEach(System.out::println);
 
}

映射(Map)

結(jié)合Function接口,該操作能將流對象中的每個元素映射為另一種元素,實現(xiàn)元素類型的轉(zhuǎn)換。

?
1
2
3
4
5
6
7
8
9
10
public static void streamMapTest() {
  lists.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);
 
  System.out.println("自定義映射規(guī)則");
  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);
 
}

在上面簡單介紹了三種常用的操作,這三種操作極大簡化了集合的處理。接下來,介紹幾種完結(jié)方法:

完結(jié)方法

“變換”過程之后,需要獲取結(jié)果,即完成操作。下面我們來看相關(guān)的操作:

匹配(Match)

用來判斷某個predicate是否和流對象相匹配,最終返回Boolean類型結(jié)果,例如:

?
1
2
3
4
5
6
7
8
9
public static void streamMatchTest() {
  //流對象中只要有一個元素匹配就返回true
  boolean anyStartWithA = lists.stream().anyMatch((s -> s.startsWith("a")));
  System.out.println(anyStartWithA);
  //流對象中每個元素都匹配就返回true
  boolean allStartWithA
      = lists.stream().allMatch((s -> s.startsWith("a")));
  System.out.println(allStartWithA);
}

收集(Collect)

在對經(jīng)過變換之后,我們將變換的Stream的元素收集,比如將這些元素存至集合中,此時便可以使用Stream提供的collect方法,例如:

?
1
2
3
4
5
public static void streamCollectTest() {
  List<String> list = lists.stream().filter((p) -> p.startsWith("a")).sorted().collect(Collectors.toList());
  System.out.println(list);
 
}

計數(shù)(Count)

類似sql的count,用來統(tǒng)計流中元素的總數(shù),例如:

?
1
2
3
4
public static void streamCountTest() {
  long count = lists.stream().filter((s -> s.startsWith("a"))).count();
  System.out.println(count);
}

規(guī)約(Reduce)

reduce方法允許我們用自己的方式去計算元素或者將一個Stream中的元素以某種規(guī)律關(guān)聯(lián),例如:

?
1
2
3
4
5
6
public static void streamReduceTest() {
  Optional<String> optional = lists.stream().sorted().reduce((s1, s2) -> {
    System.out.println(s1 + "|" + s2);
    return s1 + "|" + s2;
  });
}

執(zhí)行結(jié)果如下:

?
1
2
3
4
5
a1|a2
a1|a2|b1
a1|a2|b1|b2
a1|a2|b1|b2|b3
a1|a2|b1|b2|b3|o1

并行Stream VS 串行Stream

到目前我們已經(jīng)將常用的中間操作和完結(jié)操作介紹完了。當然所有的的示例都是基于串行Stream。接下來介紹重點戲——并行Stream(parallel Stream)。并行Stream基于Fork-join并行分解框架實現(xiàn),將大數(shù)據(jù)集合切分為多個小數(shù)據(jù)結(jié)合交給不同的線程去處理,這樣在多核處理情況下,性能會得到很大的提高。這和MapReduce的設(shè)計理念一致:大任務(wù)化小,小任務(wù)再分配到不同的機器執(zhí)行。只不過這里的小任務(wù)是交給不同的處理器。

通過parallelStream()創(chuàng)建并行Stream。為了驗證并行Stream是否真的能提高性能,我們執(zhí)行以下測試代碼:

首先創(chuàng)建一個較大的集合:

?
1
2
3
4
5
List<String> bigLists = new ArrayList<>();
  for (int i = 0; i < 10000000; i++) {
    UUID uuid = UUID.randomUUID();
    bigLists.add(uuid.toString());
  }

測試串行流下排序所用的時間:

?
1
2
3
4
5
6
7
8
private static 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("串行排序: %d ms", millis));
 
}

測試并行流下排序所用的時間:

?
1
2
3
4
5
6
7
8
private static void parallelStreamSortedTest(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("并行排序: %d ms", millis));
 
}

結(jié)果如下:

          串行排序: 13336 ms
          并行排序: 6755 ms

看到這里,我們確實發(fā)現(xiàn)性能提高了約么50%,你也可能會想以后都用parallel Stream不久行了么?實則不然,如果你現(xiàn)在還是單核處理器,而數(shù)據(jù)量又不算很大的情況下,串行流仍然是這種不錯的選擇。你也會發(fā)現(xiàn)在某些情況,串行流的性能反而更好,至于具體的使用,需要你根據(jù)實際場景先測試后再決定。

懶操作

上面我們談到Stream盡可能以延遲的方式運行,這里通過創(chuàng)建一個無窮大的Stream來說明:

首先通過Stream的generate方法來一個自然數(shù)序列,然后通過map變換Stream:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//遞增序列
class NatureSeq implements Supplier<Long> {
   long value = 0;
 
   @Override
   public Long get() {
     value++;
     return value;
   }
 }
 
public void streamCreateTest() {
   Stream<Long> stream = Stream.generate(new NatureSeq());
   System.out.println("元素個數(shù):"+stream.map((param) -> {
     return param;
   }).limit(1000).count());
 
 }

執(zhí)行結(jié)果為:

       元素個數(shù):1000

我們發(fā)現(xiàn)開始時對這個無窮大的Stream做任何中間操作(如:filter,map等,但sorted不行)都是可以的,也就是對Stream進行中間操作并生存一個新的Stream的過程并非立刻生效的(不然此例中的map操作會永遠的運行下去,被阻塞住),當遇到完結(jié)方法時stream才開始計算。通過limit()方法,把這個無窮的Stream轉(zhuǎn)為有窮的Stream。

總結(jié)

以上就是Java Lambda快速入門詳解的全部內(nèi)容,看完本文后大家是不是對Java Lambda有了更深的了解,希望本文對大家學(xué)習(xí)Java Lambda能有所幫助。

延伸 · 閱讀

精彩推薦
  • JAVA教程Java編寫猜數(shù)字小游戲

    Java編寫猜數(shù)字小游戲

    這篇文章主要為大家詳細介紹了Java編寫的猜數(shù)字小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下 ...

    lijiao2702020-01-07
  • JAVA教程java HashMap通過value反查key的代碼示例

    java HashMap通過value反查key的代碼示例

    本文講解了java HashMap通過value反查key的方法,直接提供代碼供大家參考使用 ...

    java教程網(wǎng)1612019-10-20
  • JAVA教程淺談java封裝

    淺談java封裝

    封裝封裝就是將屬性私有化,提供公有的方法訪問私有的屬性。*實現(xiàn)封裝的步驟:(1)修改屬性的可見性來限制對屬性的訪問。(2)為每個屬性創(chuàng)建一對...

    hebedich3002019-12-13
  • JAVA教程java文件操作練習(xí)代碼 讀取某個盤符下的文件

    java文件操作練習(xí)代碼 讀取某個盤符下的文件

    這篇文章主要介紹了java讀取某個盤符下的文件示例,代碼中要求的是絕對路徑,編譯過程中要注意絕對路徑問題和異常的抓取 ...

    java教程網(wǎng)1842019-11-01
  • JAVA教程java多線程編程之使用Synchronized塊同步變量

    java多線程編程之使用Synchronized塊同步變量

    我們可以通過synchronized塊來同步特定的靜態(tài)或非靜態(tài)方法。要想實現(xiàn)這種需求必須為這些特性的方法定義一個類變量,然后將這些方法的代碼用synchronized塊...

    java技術(shù)網(wǎng)2602019-11-04
  • JAVA教程java解一個比較特殊的數(shù)組合并題

    java解一個比較特殊的數(shù)組合并題

    這篇文章主要介紹了java解一個比較特殊的數(shù)組合并題,需要的朋友可以參考下 ...

    Java教程網(wǎng)5252019-11-23
  • JAVA教程Android應(yīng)用開發(fā)之將SQLite和APK一起打包的方法

    Android應(yīng)用開發(fā)之將SQLite和APK一起打包的方法

    這篇文章主要介紹了Android應(yīng)用開發(fā)之將SQLite和APK一起打包的方法,文章時間較早,盡管現(xiàn)在開發(fā)環(huán)境已大都遷移至Android Studio上,但打包原理依然相同,需要的朋...

    libuchao3372020-01-03
  • JAVA教程Java for循環(huán)詳解

    Java for循環(huán)詳解

    這篇文章主要介紹了Java for循環(huán)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來...

    東邊的雨田3692019-06-23
主站蜘蛛池模板: 国内自拍网站 | 伦一区二区三区中文字幕v亚洲 | 亚洲一区视频在线 | 亚洲免费在线播放 | 亚洲在线一区二区 | 在线观看一区二区三区视频 | 日韩欧美一区二区免费 | 国产综合在线视频 | 美女视频黄的免费 | 亚洲综合二区 | 国产综合视频 | 亚洲一区中文字幕在线 | 亚洲一区中文 | 一区二区三区国产 | 中文字幕不卡在线观看 | 色综合一区二区 | 精品久久一区 | 欧美1区2区3区 | 一区二区三区亚洲 | 成年人免费观看在线视频 | 久久av一区二区三区 | 99亚洲伊人久久精品影院 | 精品久久一区 | 欧美国产另类 | 无毛网站| 亚洲不卡 | av手机在线播放 | 91网页版 | 亚洲在线中文字幕 | 精品国产青草久久久久福利 | 国产日韩一级片 | 国产精品久久久久久 | 欧美激情精品久久久久久变态 | 黄色片视频免费看 | 国产美女精品一区二区三区 | 亚洲国产综合在线 | 亚洲精品一区二区三区蜜桃久 | 黄色a视频 | 久久久天堂国产精品女人 | 色站综合| 欧美午夜影院 |