JDK8(三)Java Stream API

一、什麼是Java Stream API?

1.1、簡介

Java Stream函數式編程接口最初是在Java 8中引入的,並且與lambda一起成爲Java開發的里程碑式的功能特性,它極大的方便了開放人員處理集合類數據的效率。
Java Stream就是一個數據流經的管道,並且在管道中對數據進行操作,然後流入下一個管道。
管道的功能包括:Filter(過濾)、Map(映射)、sort(排序)等,集合數據通過Java Stream管道處理之後,轉化爲另一組集合或數據輸出。
在這裏插入圖片描述

二、如何獲取Stream流?

(完整代碼在下面,放到一個類裏面了)

package com.zicheng.stream;

import java.util.*;
import java.util.stream.Stream;

/**
 * 子誠
 * Description:集合、map、數組 獲取流
 * 時間:2020/4/1 16:44
 */
public class Demo_GetStream {
    public static void main(String[] args) {
        //list獲取Stream流
        List<String> list = new ArrayList<>();
        Stream<String> listStream = list.stream();

        //set獲取Stream流
        Set<String> set = new HashSet<>();
        Stream<String> setStream = set.stream();

        //獲取Map的Stream流
        Map<String, String> map = new HashMap<>();
        //獲取map中 key 的Stream流
        Stream<String> keyStream = map.keySet().stream();
        //獲取map中 value 的Stream流
        Stream<String> valueStream = map.values().stream();
        //獲取 entry 的Stream流
        Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();

        //數組獲取Stream流
        String[] array = {"河南省", "新鄉市", "河南師範大學"};
        Stream<String> arrayStream = Stream.of(array);
    }
}

2.1、Collection 轉換爲管道流

注:
java.util.Collection 接口中加入了default方法 stream 用來獲取流,所以其所有實現類均可獲取流。

關鍵代碼:
list.stream(); set.stream();

2.2、Map 轉換爲管道流

注:
java.util.Map 接口不是 Collection 的子接口,且其K-V數據結構不符合流元素的單一特徵,所以需要分別獲取對應的流;需要分key、value或entry等情況。

關鍵代碼:
map.keySet().stream();
map.values().stream();
map.entrySet().stream();

3.3、數組轉換爲管道流

注:
如果使用的不是集合(Collection)或映射(map)而是數組,由於數組對象不可能添加默認方法,所以 Stream 接口中提供了靜態方法 of

關鍵代碼:
Stream.of(array);

3.4、文本文件轉換爲管道流

通過Files.lines方法將文本文件轉換爲管道流,下圖中的Paths.get()方法作用就是獲取文件,是Java NIO的API!

Stream<String> lines = Files.lines(Paths.get("file.txt"));

三、常用方法

3.0、全部代碼

package com.zicheng.stream;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * 子誠
 * Description:Stream中的常用方法
 * 時間:2020/4/1 18:27
 */
public class StreamFunctionDemo {
    public static void main(String[] args) {
        StreamFunctionDemo demo = new StreamFunctionDemo();
        //方法1:逐一處理:forEach
        demo.test_forEach();

        //方法2:過濾:filter
        demo.test_filter();

        //方法3:映射:map
        demo.test_map();

        //方法4:排序:sorted
        demo.test_sorted();

        //方法6:統計個數test_count()
        demo.test_count();
        
        //方法7:測試截取:limit
        demo.test_limit();
        
        //方法8:跳過:skip
        demo.test_skip();
        
        //方法9:組合:concat
        demo.test_concat();
    }

    //方法1:逐一處理:forEach
    void test_forEach() {
        String[] array = {"河南省", "新鄉市", "河南師範大學"};
        Stream<String> arrayStream = Stream.of(array);
        /**
         * parallel()函數表示對管道中的元素進行並行處理而不是串行處理。
         * 但是這樣就有可能導致管道流中後面的元素先處理,前面的元素後處理,也就是元素的順序無法保證。
         * 數據量大的話,就能觀察到數據順序是無法保證的.
         * 不想用,不用
         */
        arrayStream.parallel().forEach(item -> System.out.println(item));

        arrayStream.forEach(item -> {
            //在這個地方可以對每個item進行操作
            System.out.println(item);
        });
    }

    //方法2:過濾:filter
    void test_filter() {
        // 獲取以“河南”開頭的數據項
        List<String> nameStrs = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        List<String> list = nameStrs.stream()
                .filter(s -> s.startsWith("河南"))
                // 轉換成了List的數據結構,方便接收和打印
                .collect(toList());
        System.out.println(list);
    }

    //方法3:映射:map;將集合中的每一個字符串全部大寫
    void test_map() {
        // Arrays.asList(),將數組轉換爲字符串
        List<String> players = Arrays.asList("Kobe Bean Bryant", "James", "Harden", "Curry", "Durant");
        List<String> list = players.stream()
                //s-> s.toUpperCase(),可以替換爲String::toUpperCase(方法引用)
                .map(String::toUpperCase)
                // 轉換成了List的數據結構,方便接收和打印
                .collect(toList());
        System.out.println(list);
    }

    //方法4:排序:sorted
    void test_sorted() {
        List<Integer> nums = Arrays.asList(2, 6, 5, 4, 8, 7, 9);
        //sorted,默認是升序
        List<Integer> list = nums.stream().sorted().collect(toList());
        System.out.println(list);
        //如果想要降序的話
        Collections.reverse(list);
        System.out.println(list);
    }

    //方法5:轉換:collect
    void test_collect() {
        //list,set可以互轉。
        //list轉成map的話,index當做key,元素就當做value
        //具體,有時間再寫
    }

    //方法6:統計個數:count
    void test_count() {
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        long count = school.stream()
                .filter(s -> s.startsWith("河南"))
                .count();
        //打印個數
        System.out.println(count);
    }

    //方法7:截取:limit
    void test_limit() {
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        List<String> limit = school.stream()
                .limit(2)
                .collect(toList());
        //打印結果
        System.out.println(limit);
    }

    //方法8:跳過:skip
    void test_skip() {
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        List<String> skip = school.stream()
                //跳過前兩個
                .skip(2)
                .collect(toList());
        //打印結果
        System.out.println(skip);
    }

    //方法9:組合:concat
    void test_concat() {
        List<String> country = Arrays.asList("地球", "中華人民共和國");
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        //將上面的兩個集合拼接
        List<String> address = Stream.concat(country.stream(), school.stream())
                .collect(toList());
        //打印結果
        System.out.println(address);
    }
}


3.1、逐一處理:forEash

注:
雖然操作以及名稱,都和for很像,但是原理是不一樣的。
一個是管道流,一個是遍歷。

//方法1:逐一處理
 void test_forEach() {
        String[] array = {"河南省", "新鄉市", "河南師範大學"};
        Stream<String> arrayStream = Stream.of(array);
        /**
         * parallel()函數表示對管道中的元素進行並行處理而不是串行處理。
         * 但是這樣就有可能導致管道流中後面的元素先處理,前面的元素後處理,也就是元素的順序無法保證。
         * 數據量大的話,就能觀察到數據順序是無法保證的.
         * 不想用,不用
         */
        arrayStream.parallel().forEach(item -> System.out.println(item));

        arrayStream.forEach(item -> {
            //在這個地方可以對每個item進行操作
            System.out.println(item);
        });
    }

在這裏插入圖片描述

3.2、過濾:filter

注:
可以通過 filter 方法,將一個轉換成另一個子集流

//方法2:過濾
void testFilter() {
    List<String> nameStrs = Arrays.asList("河南省", "新鄉市", "河南師範大學");
    List<String> list = nameStrs.stream()
            .filter(s -> s.startsWith("河南"))
            //轉換成了List的數據結構,方便接受和打印
            .collect(toList());
    System.out.println(list);
}

在這裏插入圖片描述

3.3、映射:map

注:
如果需要將流中的元素映射到另一個流中,可以使用 map 方法。

	//方法3:映射:map;將集合中的每一個字符串全部大寫
    void test_map() {
        // Arrays.asList(),將數組轉換爲字符串
        List<String> players = Arrays.asList("Kobe Bean Bryant", "James", "Harden", "Curry", "Durant");
        List<String> list = players.stream()
                //s-> s.toUpperCase(),可以替換爲String::toUpperCase(方法引用)
                .map(String::toUpperCase)
                // 轉換成了List的數據結構,方便接收和打印
                .collect(toList());
        System.out.println(list);
    }

在這裏插入圖片描述

3.4、排序:sort

	//方法4:排序:sorted
    void test_sorted() {
        List<Integer> nums = Arrays.asList(2, 6, 5, 4, 8, 7, 9);
        //sorted,默認是升序
        List<Integer> list = nums.stream().sorted().collect(toList());
        System.out.println(list);
        //如果想要降序的話
        Collections.reverse(list);
        System.out.println(list);
    }

在這裏插入圖片描述

3.5、轉換:collect

常用的,上面已經提及到了。

	//方法5:轉換:collect
    void test_collect() {
        //list,set可以互轉。
        //list轉成map的話,index當做key,元素就當做value
        //具體,有時間再寫
    }

3.6、統計個數:count

//方法6:統計個數:count
    void test_count() {
        List<String> nameStrs = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        long count = nameStrs.stream()
                .filter(s -> s.startsWith("河南"))
                .count();
        //打印個數
        System.out.println(count);
    }

在這裏插入圖片描述

3.7、截取:limit

	//方法7:測試截取:limit
    void test_limit(){
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        List<String> limit= school.stream()
        		// 截取前兩個
                .limit(2)
                .collect(toList());
        //打印結果
        System.out.println(limit);
    }

在這裏插入圖片描述

3.8、跳躍:skip

	//方法8:跳過:skip
    void test_skip(){
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        List<String> skip = school.stream()
                //跳過前兩個
                .skip(2)
                .collect(toList());
        //打印結果
        System.out.println(skip);
    }

在這裏插入圖片描述

3.9、組合拼接:concat

	//方法9:組合:concat
    void test_concat() {
        List<String> country = Arrays.asList("地球", "中華人民共和國");
        List<String> school = Arrays.asList("河南省", "新鄉市", "河南師範大學");
        //將上面的兩個集合拼接
        List<String> address = Stream.concat(country.stream(), school.stream())
        .collect(toList());
        //打印結果
        System.out.println(address);
    }

在這裏插入圖片描述

四、推薦鏈接

倜儻的雷哥:https://ke.qq.com/teacher/316518226 (騰訊課堂,講的很好,推薦一波)
風騷的稽哥:https://ke.qq.com/teacher/1579106394 (騰訊課堂,風趣有味,知識淵博)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章