Java Stream函數式編程圖文詳解(二):管道數據處理

Java Stream函數式編程?案例圖文詳解管道數據處理

1、Java Stream管道數據處理操做

在本號以前發佈的文章《Java Stream函數式編程?用過都說好,案例圖文詳解送給你》中,筆者對Java Stream的介紹以及簡單的使用方法給你們作了介紹。在開始本文以前,咱們有必要介紹一下這張Java Stream 數據處理過程圖,圖中主要分三個部分:java

  • 將數組、集合類、文本文件轉換爲管道流(圖中的藍色方塊的部分,在本號的上一篇文章中已經給你們介紹過了)
  • Java Stream管道數據處理操做(也就是下圖中中間的虛線內的數據處理操做,本文的主要內容)
  • 管道流處理結果的聚合、累加、計數、轉換爲集合類等操做(圖中的綠色方塊部分)

須要注意的是:Java Stream的中間數據處理操做的輸入是一個管道流(Stream),輸出仍然是一個管道流(Stream)。下面咱們就來詳細的學習一下!在上一篇文章中,咱們給你們講了這樣一個例子:spring

List<string> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
    
    List<string> list = nameStrs.stream()
            .filter(s -&gt; 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()都屬於中間數據處理操做,下面就給你們講解一下這些函數的詳細用法。編程

2、filter管道數據過濾

根據筆者的的經驗,filter()是Stream API最有用的操做之一,它能夠過濾掉不符合條件的元素。下面的代碼過濾掉管道中的不是以L開頭的字符串元素。處理完成以後,管道中剩下的元素是:[Lion, Lemur]數組

Stream<string> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
     .filter(s -&gt; s.startsWith("L"));

若是沒有學過lambda表達式的同窗,可能對上面的代碼感到困惑。其實很簡單,lambda表達式用來表達函數,箭頭左側是參數,箭頭右側是函數體。函數的參數類型和返回值類型,會根據上下文作自動化的判斷,不用你管。上文中的lambda表達式寫成函數是這樣的springboot

public static boolean filterUpperL(String str){
        return str.startsWith("L");
    }
    
    //.filter(BootLaunchApplicationTests::filterUpperL)

我甚至見過有的人排斥使用lambda表達式,說這種語法使代碼的可讀性降低。這個怎麼說呢,若是一篇專業期刊中包含英語專業名詞與引用,而讀者恰巧不會英語就不想讀了,我以爲這不是文章的問題,而是讀者的問題。並且lamdba表達式在各類編程語言裏面獲得普遍的使用,提升編碼效率。其實很簡單:箭頭左側是參數,箭頭右側是函數體,你已經學會了!編程語言

3、Limit與Skip管道數據截取

Stream<string> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").limit(2);
     Stream<string> startsWithT = Stream.of("Monkey", "Lion", "Giraffe", "Lemur").skip(2);
  • limt方法傳入一個整數n,用於截取管道中的前n個元素。通過管道處理以後的數據是:[Monkey, Lion]。
  • skip方法與limit方法的使用相反,用於跳過前n個元素,截取從n到末尾的元素。通過管道處理以後的數據是: [Giraffe, Lemur]

4、Distinct元素去重

咱們還可使用distinct方法對管道中的元素去重,涉及到去重就必定涉及到元素之間的比較,distinct方法時調用Object的equals方法進行對象的比較的,若是你有本身的比較規則,能夠重寫equals方法。函數式編程

Stream<string> uniqueAnimals = Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
            .distinct();

上面代碼去重以後的結果是: ["Monkey", "Lion", "Giraffe", "Lemur"]函數

5、Sorted排序

默認的狀況下,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));

6、Map數據轉換處理

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 -&gt; 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類型的返回值。

期待您的關注

相關文章
相關標籤/搜索