程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java函數式編程(三):列表的轉化

Java函數式編程(三):列表的轉化

編輯:關於JAVA

Java函數式編程(三):列表的轉化。本站提示廣大學習愛好者:(Java函數式編程(三):列表的轉化)文章只能為提供參考,不一定能成為您想要的結果。以下是Java函數式編程(三):列表的轉化正文


列表的轉化

將聚集轉化成一個新的聚集就和遍歷它一樣簡略。假定我們要將列表中的名字轉化玉成年夜寫的。我們看下都有哪些完成方法。

Java中的字符串是弗成變的,所以它沒法轉變。我們可以生成新的字符串,用來調換列表華夏有的元素。但是如許做的話,本來列表就沒了;還有一個成績,本來的列表能夠也是弗成變的,好比Arrays.asList()生成的,所以修正本來的列表這招不可。還有一個缺陷就是如許做很難並行操作。

生成一個新的全年夜寫的列表是個不錯的選擇。

乍聽起來這個建議弱爆了;機能是我們都很存眷的一個成績。使人受驚的是,函數式編程平日要比敕令式的機能要高,我們在153頁的機能成績中會講到。

我們先開端用這個聚集生成一個年夜寫字母的新聚集吧。

final List<String> uppercaseNames = new ArrayList<String>();
for(String name : friends) {
uppercaseNames.add(name.toUpperCase());
}

在敕令式的代碼中,我們先創立一個空列表,然後把年夜寫的名字填充出來,在遍歷本來列表的進程中,每次拔出一個。為了改良成函數式的版本,我們第一步可以斟酌采取19頁遍歷列表中提到的誰人外部迭代器forEach來調換一下for輪回,正以下例所示的那樣。

final List<String> uppercaseNames = new ArrayList<String>();
friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
System.out.println(uppercaseNames);

我們用了外部迭代器,但還得新建一個列表,然後再把元素拔出到外面。我們還可以進一步改良。

應用lambda表達式

一個新引入的Stream接口外面,有個map辦法,它可以贊助我們闊別可變性,並使代碼看起來更簡練。Steam有點像聚集的迭代器,同時它還供給了流函數(fluent functions)的功效。應用這個接口的辦法,我們可以把一系列挪用給組合起來,使代碼讀起來就像描寫成績的次序一樣,可讀性更強。

Steam的map辦法可以用來將輸出序列轉化成一個輸入的序列——這和我們要做的任務異常婚配。


friends.stream()
.map(name -> name.toUpperCase())
.forEach(name -> System.out.print(name + " "));
System.out.println();

JDK8中的一切聚集都支撐這個stream辦法,它把聚集封裝成一個Steam實例。map辦法對Stream中的每一個元素都挪用了指定的lambda表達式或許代碼塊。map辦法跟forEach辦法很紛歧樣, forEach只是簡略的對聚集中的元素履行了一下指定的函數。而map辦法把lambda表達式的運轉成果收齊起來,前往一個成果集。最初我們用forEach辦法打印了一切的元素。

新聚集中的名字全都是年夜寫的了:

BRIAN NATE NEAL RAJU SARA SCOTT

map辦法很合適把一個輸出聚集轉化成一個新的輸入聚集。這個辦法確保了輸出輸入序列的元素的數目是雷同的。但是輸出元素和輸入元素的類型可所以紛歧樣的。在這個例子中,我們輸出和輸入的都是字符串的聚集。我們可以傳給map辦法一段代碼,讓它前往好比說名字中包括字符的個數。如許的話,輸出的照樣字符串的序列,而輸入的倒是數字序列了,就像上面如許。

friends.stream()
.map(name -> name.length())
.forEach(count -> System.out.print(count + " "));

成果是每一個名字中字母的個數:

5 4 4 4 4 5

應用了lambda表達式的以後版本,防止了顯式的修正操作;如許的代碼異常簡練。如許寫不再須要初始化空的聚集和誰人渣滓變量了;這個變量乖乖的躲到了底層完成外面了。

應用辦法援用

我們還可使用辦法援用讓它變得更簡練一些。在須要傳入函數式接口的完成的處所,Java編譯器可以接收lambda表達式或許是辦法援用。有了這個特征,用String::toUpperCase便可以調換失落name -> name.toUpperCase()了,就像如許:

friends.stream()
.map(String::toUpperCase)
.forEach(name -> System.out.println(name));

當參數傳入到這個生成的辦法——函數式接口的籠統辦法的完成——外面的時刻,Java會去挪用這個String參數的toUpperCase辦法。這個參數援用在這裡就隱蔽起來了。像後面這類簡略的場景,我們可以用辦法援用來調換失落lambda表達式;更多的內容看一下26頁的甚麼時刻應當應用辦法援用。

小同伴提問了:
甚麼時刻應當應用辦法援用?

當應用Java編程的時刻,平日我們用lambda表達式的時刻要比喻法援用多很多。但這其實不意味著辦法援用不主要或許沒啥用途。當lambda表達式異常冗長的時刻,它是一個很好的替換計劃,它直接挪用了實例辦法或許靜態辦法。也就是說,假如lambda表達式只是傳遞了一下參數給辦法挪用的話,我們應當改用辦法援用。
像如許的lambda表達式,有點像Tom Smykowski在片子下班一條蟲中講的那樣,它的任務就是"從客戶那把需求拿給軟件工程師"。由於這個,我把這類重組成辦法援用的形式叫做下班一條蟲形式。
除簡練外,應用辦法援用,辦法名字自己的寄義和感化可以更好的表現出來。
應用辦法援用面前,編譯器起到了很症結的感化。辦法援用的目的對象和參數都邑從這個生成的辦法裡傳出去的參數那推導出來。這才使得你可使用辦法援用寫出比應用lambda表達式更簡練的代碼。不外,假如參數在傳遞給辦法之前或許挪用成果在前往以後要被修正的話,這類方便的寫法我們就用不了了。

在後面這個例子中,辦法援用是援用了一個實例辦法。辦法援用還可以援用一個靜態辦法和接收傳參的辦法。前面我們會看到如許的例子。

lambda表達式能贊助我們遍歷聚集,而且停止聚集的轉化。就像上面我們行將看到的,它還能贊助我們疾速的從聚集當選取一個元素。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved