Lambda、stream

來源:互聯網
上載者:User

標籤:ons   抽象   string類   parameter   理解   str   應用   隨機   箭頭   

 

Lambda  1.Lambda運算式概念

Lambda運算式是一個匿名函數,可理解為是一段可以傳遞的代碼(即將函數像資料一樣傳遞)。

Lambda運算式需要函數式介面(即只有一個抽象方法的介面)的支援。

Lambda操作符:->,該箭頭一樣的操作符將Lambda運算式拆分成兩側,

                          其中左側寫Lambda運算式的參數列表(介面中抽象方法的參數);右側寫Lambda運算式所需執行的功能(抽象方法的實現),即Lambda體。

 

2.Lambda運算式的基本文法

文法:

(parameters) -> expression

(parameters) ->{ statements; }

 

3.基礎寫法

我們先看幾個簡單的Lambda運算式的例子:

// 1. 不需要參數,傳回值為 5 

     () -> 5

// 2. 接收一個參數(數字類型),返回其2倍的值 

      x -> 2 * x

// 3. 接受2個參數(數字),並返回他們的差值 

      (x, y) ->x –y

// 4. 接收2個Integer型整數,返回他們的和 

      (Integer x, Integer y) ->x + y

// 5. 接受一個 string 對象,並在控制台列印,不返回任何值(看起來像是返回void) 

        (String s) ->System.out.print(s)

 

通過上述幾個簡單例子我們總結一下Lambda運算式的基本寫法:

1).左側類型可以不寫;

2).左側只有一個參數時小括弧也可省略;

3)右側只有一條語句時,大括弧和return都可省略;

4)右側有多條語句,必須要有大括弧。

 

4.Lambda運算式用在for迴圈中

String[] names={"Mike","Mary","Eric","Lucy","Rose"};

List<String> students=Arrays.asList(names);

// 以前的迴圈方式 

for (String student: students) { 

  System.out.print(student+ "; "); 

   

//方式一: 使用 lambda 運算式以及函數操作

students.forEach((student) -> System.out.print(student+ "; ")); 

    

//方式二:使用雙冒號操作符(Lambda運算式方法引用的第一種文法格式,下面會講  )

students.forEach(System.out::println);

 

5.Lambda運算式的方法引用(雙冒號操作符)

當Lambda體中的內容已有方法實現,此時可以使用方法引用,有三種文法格式:

1)對象::執行個體方法名

例:Consumer<String> con=(x)->System.out.println(x);可以寫為:

Consumer<String> con=System.out::println;//System.out即PrintWriter對象

2)類::靜態方法名

例:Comparator<Integer> com=(x,y)->Integer.compare(x,y);可以寫為:

Comparator<Integer> com=Integer::compare;

3)類::執行個體方法名

例:BiPredicate<String,String> bp=(x,y)->x.equals(y);

BiPredicate<String,String> bp=String::equals;

注意:只有當Lambda參數列表中的第一個參數是執行個體方法的調用者,而第二個參數是執行個體方法的參數時,可以使用第3)種文法格式類::執行個體方法名。如上述例子中第一個參數x是執行個體方法x.equals(y)的調用者,第二個參數y是方法的參數。

 

資料流Stream 1.流的擷取

1)通過集合Collection擷取

List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5));

 

Stream<Integer> stream = list.stream();

2)通過數組擷取

String[] array = {"are","you","ok"};

 

Stream<String> stream = Array.stream(array);

//對於基本類型數組的處理

int[] array = {1,2,3,4,5};

 

//此時Arrays.stream(array)擷取的是一個IntStream對象

Stream<Integer> stream = Arrays.stream(array).boxed();    

3)通過值擷取(此方式存在缺陷)

Stream<String> stream = Stream.of("are","you","ok");

 

2.篩選filter

filter函數接收一個Lambda運算式作為參數,該運算式返回boolean,在執行過程中,流將元素逐一輸送給filter,並篩選出執行結果為true的元素;

//篩選出列表中的非空項

 

List<String> list = Arrays.asList("are","you","","ok");

 

List<String> filted = list.stream()

                    .filter(x-> !x.empty())

                    .collect(Collectors.toList());

 

3.去重、截取、跳過

去重distinct:

List<String> list = Arrays.asList("are","you","you","ok");

List<String> distincted = list.stream()

                        .distinct()

                        .collect(Collectors.toList());

截取流的前n個元素: .limit(3)

跳過流的前n個元素: .skip(2)

 

4.映射 map

對流中的每個元素執行一個函數,使得元素轉換成另一種類型輸出。流會將每一個元素輸送給map函數,並執行map中的Lambda運算式,最後將執行結果存入一個新的流中。 

如:將 list 中每一個 Integer類型元素自增後轉化為 String類型

List<Integer> list = Arrays.asList(1,2,3,4,5);

 

List<String> result = list.stream()

                    .map(x->String.valueOf(++x))

                    .collect(Collectors.toList());

 

5.合并多個流 flatMap

List<String> list1 = .....

List<String> list2 = ...

List<List<String>> list = Arrays.asList(list1,list2);

 

//將list中的list1,list2合并為一個List<String>

List<String> listsum = list.stream()

                          .flatMap(List::stream)

                          .collect(Collectors.toList());

 

 

以下一個實際的應用例子:列出 list 中各不相同的單詞

List<String> list = new ArrayList<String>();

list.add("I am a boy");

list.add("I love the girl");

list.add("But the girl loves another girl");

 

list.stream().map(line->line.split(" "))    //將每一個項分詞,並映射為數組

//將每一個分項數組組合并到主流中,形成一個包含所有分項數組的總數組流

            .flatMap(Arrays::stream)      

            .distinct();                   //去重

            .forEach(System.out::println);   //列印

 

6.匹配元素

1) 是否匹配任一元素:anyMatch

2) 是否匹配所有元素:allMatch

3) 是否未匹配所有元素:noneMatch

 

7.擷取元素

1) 擷取任一元素 :findAny

2) 擷取第一個元素:findFirst

Optional 對象介紹

Optional是Java8新加入的一個容器,這個容器只存1個或0個元素,它用於防止出現NullpointException,它提供如下方法:

  • isPresent()  判斷容器中是否有值。
  • ifPresent(Consume lambda)  容器若不為空白則執行括弧中的Lambda運算式。
  • T get()  擷取容器中的元素,若容器為空白則拋出NoSuchElement異常。
  • T orElse(T other)  擷取容器中的元素,若容器為空白則返回括弧中的預設值。

 

8.遍曆流 forEach

forEach方法遍曆流中每個元素,參數為一個Lambda運算式,用於對每一個遍曆的元素執行的操作;

//輸出10個隨機數

Random random = new Random();

random.ints().limit(10).forEach(System.out::println);

 

Lambda、stream

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.