java Stream流,方法引用


1.Stream流

1.1兩種獲取流的方法

java.util.stream.Stream<T> 是Java 8新加入的最常用的流接口。(這並不是一個函數式接口。)

獲取一個流非常簡單,有以下幾種常用的方式:
所有的 Collection 集合都可以通過 stream 默認方法獲取流;
Stream 接口的靜態方法 of 可以獲取數組對應的流。
根據Collection獲取流
import
 java.util.*; import java.util.stream.Stream; public class Demo04GetStream {     public static void main(String[] args) {         List<String> list = new ArrayList<>();         // ...         Stream<String> stream1 = list.stream();         Set<String> set = new HashSet<>();         // ...         Stream<String> stream2 = set.stream();         Vector<String> vector = new Vector<>();         // ...

  Stream<String> stream3 = vector.stream();
    }

 }
根據Map獲取流
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class Demo05GetStream {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        // ...
        Stream<String> keyStream = map.keySet().stream();
        Stream<String> valueStream = map.values().stream();
        Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
    }
}
根據數組獲取流
如果使用的不是集合或映射而是數組,由於數組對象不可能添加默認方法,所以 Stream 接口中提供了靜態方法
of ,使用很簡單:
import java.util.stream.Stream;
public class Demo06GetStream {
    public static void main(String[] args) {
        String[] array = { "張無忌", "張翠山", "張三豐", "張一元" };
        Stream<String> stream = Stream.of(array);
    }

1.2常用方法

流模型的操作很豐富,這里介紹一些常用的API。這些方法可以被分成兩種:
延遲方法:返回值類型仍然是 Stream 接口自身類型的方法,因此支持鏈式調用。(除了終結方法外,其余方
法均為延遲方法。)
終結方法:返回值類型不再是 Stream 接口自身類型的方法,因此不再支持類似 StringBuilder 那樣的鏈式調
用。本小節中,終結方法包括 count 和 forEach 方法。

逐一處理
void forEach(Consumer<? super T> action);
過濾
Stream<T> filter(Predicate<? super T> predicate);
映射
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
統計個數
long count();
取用前幾個
Stream<T> limit(long maxSize);
跳過前幾個
Stream<T> skip(long n);
組合
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

 1.3練習:集合元素處理

現在有兩個 ArrayList 集合存儲隊伍當中的多個成員姓名,要求使用傳統的for循環(或增強for循環)依次進行以
下若干操作步驟:
1. 第一個隊伍只要名字為3個字的成員姓名;存儲到一個新集合中。
2. 第一個隊伍篩選之后只要前3個人;存儲到一個新集合中。
3. 第二個隊伍只要姓張的成員姓名;存儲到一個新集合中。
4. 第二個隊伍篩選之后不要前2個人;存儲到一個新集合中。
5. 將兩個隊伍合並為一個隊伍;存儲到一個新集合中。
6. 根據姓名創建 Person 對象;存儲到一個新集合中。
7. 打印整個隊伍的Person對象信息。

兩個隊伍(集合)的代碼如下:

import java.util.ArrayList;
而 Person 類的代碼為:
import java.util.List;
public class DemoArrayListNames {
    public static void main(String[] args) {
       //第一支隊伍
        ArrayList<String> one = new ArrayList<>();
        one.add("迪麗熱巴");
        one.add("宋遠橋");
        one.add("蘇星河");
        one.add("石破天");
        one.add("石中玉");
        one.add("老子");
        one.add("庄子");
        one.add("洪七公");
        //第二支隊伍
        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("張無忌");
        two.add("趙麗穎");
        two.add("張三豐");
        two.add("尼古拉斯趙四");
        two.add("張天愛");
        two.add("張二狗");
// ....        
    }
}

而 Person 類的代碼為:

public class Person {
   
    private String name;
    public Person() {}
    public Person(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

解答:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class DemoStreamNames {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        // ...
        List<String> two = new ArrayList<>();
        // ...
        // 第一個隊伍只要名字為3個字的成員姓名;
        // 第一個隊伍篩選之后只要前3個人;
        Stream<String> streamOne = one.stream().filter(s ‐> s.length() == 3).limit(3);
        // 第二個隊伍只要姓張的成員姓名;
        // 第二個隊伍篩選之后不要前2個人;
        Stream<String> streamTwo = two.stream().filter(s ‐> s.startsWith("張")).skip(2);
        // 將兩個隊伍合並為一個隊伍;
        // 根據姓名創建Person對象;
        // 打印整個隊伍的Person對象信息。
        Stream.concat(streamOne, streamTwo).map(Person::new).forEach(System.out::println);
    }}

運行效果:

Person{name='宋遠橋'}
Person{name='蘇星河'}
Person{name='石破天'}
Person{name='張天愛'}
Person{name='張二狗'}

2.方法引用

在使用Lambda表達式的時候,我們實際上傳遞進去的代碼就是一種解決方案:拿什么參數做什么操作。那么考慮
一種情況:如果我們在Lambda中所指定的操作方案,已經有地方存在相同方案,那是否還有必要再寫重復邏輯?

雙冒號 :: 為引用運算符,而它所在的表達式被稱為方法引用。如果Lambda要表達的函數方案已經存在於某個方
法的實現中,那么則可以通過雙冒號來引用該方法作為Lambda的替代者。

2.1 通過對象名引用成員方法

 

 2.2 通過類名稱引用靜態方法

 

 2.3 通過super引用成員方法

 

 

 

 

 

 2.4 通過this引用成員方法

 

 

 2.5 類的構造器引用

 

 

 

 

 2.6 數組的構造器引用

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM