java8中Lambda表達式和Stream API

java8中Lambda表達式和Stream API

 

1、Lambda表達式

1.語法格式

Lambda是匿名函數,能夠傳遞代碼。使用「->」操做符,改操做符將lambda分紅兩部分:html

左側:指定了 Lambda 表達式須要的全部參數java

右側:指定了 Lambda 體,即 Lambda 表達式要執行的功能,也就是實現接口方法的代碼數據庫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 語法格式一:無參、無返回值  
@Test  
public void test1() {  
     Runnable runable = () -> System.out.println("hello lambda!");  
     runable.run();  
}  
   
// 語法格式二:有一個參、無返回值  
@Test  
public void test2() {  
     Consumer< String > consumer = (args) -> System.out.println("hello!"  
            + args);  
     consumer.accept("lambda");  
}  
   
// 語法格式三:有多個參、有返回值,而且有多條執行語句,用大括號包圍  
@Test  
public void test3() {  
    Comparator< Integer > com = (x, y) -> {  
        System.out.println("hello lambda!");  
        return Integer.compare(x, y);  
     };  
     int rs = com.compare(2, 2);  
     System.out.println(rs);  
}  
   
// 語法格式四:右側若是隻有一條執行語句,能夠省略大括號和return  
@Test  
public void test4() {  
    Comparator< Integer > com = (Integer x, Integer y) -> Integer.compare(x, y);  
    int rs = com.compare(2, 2);  
    System.out.println(rs);  
}  

注:lambd能夠省略接口參數類型,java編譯器會根據上下文進行類型推斷數組

2.函數式接口

(1)只包含一個抽象方法的接口,稱爲函數式接口,能夠在任意函數式接口上使用 @FunctionalInterface 註解,lambda須要函數式接口的支持。app

(2)java8內置四大核心函數式接口:dom

Consumer<T>消費型接口:void accept(T t)函數

1
2
3
4
5
6
@Test  
public void test2() {  
     Consumer< String > consumer = (args) -> System.out.println("hello!"  
            + args);  
     consumer.accept("lambda");  
}  

Supplier<T>供給型接口:T get()post

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void test5() {
     List< Integer > rs=getNumList(6,() -> (int)(Math.random()*100));
     System.out.println(rs);
}
 
public List< Integer > getNumList(int size,Supplier< Integer > sup){
     List< Integer > list=new ArrayList< Integer >();
     for (int i = 0; i < size; i++) {
         Integer e=sup.get();
         list.add(e);
     }
    return list;
}

Function<T, R>函數型接口:R apply(T t)spa

1
2
3
4
5
6
@Test  
public void test6() {  
     Function< String , Integer> fun=(str)->str.length();  
     int len=fun.apply("lambda");  
     System.out.println(len);  
}  

Predicate<T>判定型接口:boolean test(T t)code

1
2
3
4
5
6
@Test  
public void test7() {  
     Predicate< String > check=(str)->str.equals("lambda");  
     boolean rs=check.test("lambda");  
     System.out.println(rs);  
}  

3.方法引用

當要傳遞給Lambda體的操做,已經有實現的方法了,能夠使用方法引用!( lambda要實現抽象方法的參數列表,必須與方法引用的方法參數列表保持一致! )。
方法引用:使用操做符 「 ::」 將對象或類和方法的名字分隔開來。

三種主要使用狀況:

對象::方法名

1
2
3
PrintStream ps=System.out;  
Consumer< String > consumer =  ps::println;  
consumer.accept("lambda");

類::靜態方法名

1
2
3
Comparator< Integer > com = Integer::compare;  
int rs = com.compare(2, 2);  
System.out.println(rs);  

類::實例方法名(前提條件:lambda參數列表的第一個參數是實例方法的調用者,第二個參數是實例方法的入參)

1
2
BiPredicate< String ,String> check=(str1,str2)->str1.equals(str2);  
BiPredicate< String ,String> check1=String::equals;  

4.構造器引用

與函數式接口相結合,自動與函數式接口中方法兼容(須要調用的構造器方法參數列表要與函數式接口中方法的參數列表一致)

格式: ClassName::new

5.數組引用

格式: type[] :: new

2、Stream API

1.說明解釋

Stream 是 Java8 中處理集合的關鍵抽象概念,它能夠指定你但願對集合進行的操做,能夠執行很是複雜的查找、過濾和映射數據等操做。使用Stream API 對集合數據進行操做,就相似於使用 SQL 執行的數據庫查詢。也能夠使用 Stream API 來並行執行操做。簡而言之,Stream API 提供了一種高效且易於使用的處理數據的方式。流(Stream)是數據渠道,用於操做數據源(集合、數組等)所生成的元素序列。「集合講的是數據,流講的是計算! 」

注意:
①Stream 本身不會存儲元素。
②Stream 不會改變源對象。相反,他們會返回一個持有結果的新Stream。
③Stream 操做是延遲執行的。這意味着他們會等到須要結果的時候才執行。

2.Stream 操做步驟

(1)建立Stream

①能夠經過Collection系列集合提供的stream()或者parallelStream()得到

1
2
List< String > list=new ArrayList< String >();  
Stream< String > stream=list.stream();  

②能夠經過Arrays的靜態方法stream()得到數組流

1
2
Person[] ps=new Person[10];  
Stream< Person > stream=Arrays.stream(ps); 

③能夠經過Stream的靜態of()

1
Stream< String > steam=Stream.of("aa","bb","cc"); 

④能夠使用靜態方法 Stream.iterate() 和Stream.generate(), 建立無限流

(2)中間條件操做

說明:多箇中間操做能夠鏈接起來造成一個流水線,除非流水線上觸發終止操做,不然中間操做不會執行任何的處理!而在終止操做時一次性所有處理,稱爲「惰性求值」。

①篩選與切片
        filter——接收 Lambda , 從流中排除某些元素。
        limit——截斷流,使其元素不超過給定數量。
        skip(n) —— 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補
        distinct——篩選去重,經過流所生成元素的 hashCode() 和 equals() 去除重複元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List< Person > personList = Arrays.asList(  
                 new Person("李四", 20, 10),  
                 new Person("張三", 40,30),  
                 new Person("王五", 28, 15),  
                 new Person("趙六", 60, 60),  
                 new Person("趙六", 60, 60),  
                 new Person("趙六", 60, 60),  
                 new Person("田七", 8,2)  
         );  
           
         Stream< Person > stream=personList.stream();          
         stream.filter((p)->p.getAge()>20)//過濾保留age>20  
         .limit(5)//只取前兩個  
         .skip(1)//跳過前一個,返回剩下的  
         .distinct()//去重,自動定義對象去重要重寫equals和hashcode  
         .forEach(System.out::println); 

②映射
        map——接收 Lambda,將元素轉換成其餘形式或提取信息。接收一個函數做爲參數,該函數會被應用到每一個元素上,並將其映射成一個新的元素。
        flatMap——接收一個函數做爲參數,將流中的每一個值都換成另外一個流,而後把全部流鏈接成一個流

1
2
3
Stream< Person > stream=personList.stream();          
stream.map((p)->p.getName())//提取name,組成新的Stream流  
          .forEach(System.out::println);  

③排序
        sorted()——天然排序(Comparable)
        sorted(Comparator com)——定製排序

(3)執行操做

查找與匹配        allMatch——檢查是否匹配全部元素,返回boolean        anyMatch——檢查是否至少匹配一個元素,返回boolean        noneMatch——檢查是否沒有匹配的元素,返回boolean        findFirst——返回第一個元素        findAny——返回當前流中的任意一個元素        count——返回流中元素的總個數        max——返回流中最大值        min——返回流中最小值

相關文章
相關標籤/搜索