在本號以前發佈的文章《Java Stream函數式編程?用過都說好,案例圖文詳解送給你》中,筆者對Java Stream的介紹以及簡單的使用方法給你們作了介紹。在開始本文以前,咱們有必要介紹一下這張Java Stream 數據處理過程圖,圖中主要分三個部分:java
須要注意的是:Java Stream的中間數據處理操做的輸入是一個管道流(Stream),輸出仍然是一個管道流(Stream)。下面咱們就來詳細的學習一下!在上一篇文章中,咱們給你們講了這樣一個例子:spring
List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
List<String> list = nameStrs.stream()
.filter(s -> s.startsWith("L"))
.map(String::toUpperCase)
.sorted()
.collect(toList());
System.out.println(list);複製代碼
這個例子完成的功能就是:首先使用stream()函數將數組轉換爲管道流,而後對管道流中的元素進行過濾filter(),只保留L開頭的元素,而後對每個元素轉換爲大寫(map(String::toUpperCase)),而後排序sorted(),最終轉換爲List類型。通過處理以後的輸出結果是: [LEMUR, LION]
.在上面的例子中,filter()、map()、sorted()都屬於中間數據處理操做,下面就給你們講解一下這些函數的詳細用法。編程
根據筆者的的經驗,filter()
是Stream API最有用的操做之一,它能夠過濾掉不符合條件的元素。下面的代碼過濾掉管道中的不是以L開頭的字符串元素。處理完成以後,管道中剩下的元素是:[Lion, Lemur]數組
Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.filter(s -> s.startsWith("L"));複製代碼
若是沒有學過lambda表達式的同窗,可能對上面的代碼感到困惑。其實很簡單,lambda表達式用來表達函數,箭頭左側是參數,箭頭右側是函數體。函數的參數類型和返回值類型,會根據上下文作自動化的判斷,不用你管。上文中的lambda表達式寫成函數是這樣的springboot
public static boolean filterUpperL(String str){
return str.startsWith("L");
}
//.filter(BootLaunchApplicationTests::filterUpperL)複製代碼
我甚至見過有的人排斥使用lambda表達式,說這種語法使代碼的可讀性降低。這個怎麼說呢,若是一篇專業期刊中包含英語專業名詞與引用,而讀者恰巧不會英語就不想讀了,我以爲這不是文章的問題,而是讀者的問題。並且lamdba表達式在各類編程語言裏面獲得普遍的使用,提升編碼效率。其實很簡單:箭頭左側是參數,箭頭右側是函數體,你已經學會了!編程語言
Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").limit(2);
Stream<String> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").skip(2);複製代碼
咱們還可使用distinct方法對管道中的元素去重,涉及到去重就必定涉及到元素之間的比較,distinct方法時調用Object的equals方法進行對象的比較的,若是你有本身的比較規則,能夠重寫equals方法。函數式編程
Stream<String> uniqueAnimals = Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
.distinct();複製代碼
上面代碼去重以後的結果是: ["Monkey", "Lion", "Giraffe", "Lemur"]函數
默認的狀況下,sorted是按照字母的天然順序進行排序。以下代碼的排序結果是:[Giraffe, Lemur, Lion, Monkey],字數按順序G在L前面,L在M前面。第一位沒法區分順序,就比較第二位字母。學習
Stream<String> alphabeticOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.sorted();複製代碼
有的時候,咱們但願排序的規則可以自定義,這就須要使用到Comparator。有的朋友這裏可能忘了,能夠自行回顧一下java基礎的Comparator和Comparable接口。下面的代碼是根據字符串的長度排序,排序結果是:[Lion, Lemur, Monkey, Giraffe]編碼
Stream<String> lengthOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.sorted(Comparator.comparing(String::length));複製代碼
map()函數的做用是將管道流中的每個元素,以某種規則轉換爲另一個元素。下面代碼處理過的管道中的元素爲: [monkey, lion, giraffe, lemur],全部元素的字母所有小寫。
Stream<String> lowerCase = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.map(String::toLowerCase);
//這兩種寫法的實現效果是同樣的,一個是lambda表達式,一個是函數引用的方式
Stream<String> lowerCase = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.map(s -> s.toLowerCase());複製代碼
map()函數不只能夠處理數據,還能夠轉換數據的類型。以下:
IntStream lengths = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.mapToInt(String::length);複製代碼
上面代碼的處理結果是:[6, 4, 7, 5],規則是字符串的長度。將管道流的字符串,使用mapToInt方法,以String::length爲規則進行轉換。固然除了mapToInt,還爲咱們提供了mapToDouble()和mapToLong()方法。咱們能夠經過自定義轉換規則函數,返回int、double、long類型的返回值。