Stream概述以及創建Stream對象

Stream是用來操作容器中的數據,例如過濾,映射,規約,排序,查找記錄等等
Stream是和CPU打交道
集合關注的是數據的存儲,是和內存打交道
總結:集合說的是數據,Stream說的是計算

注意:
①Stream 自己不會存儲元素(數據),數據仍然是在集合當中。類似於迭代器,迭代器是用來遍歷集合的,迭代器本身也不存數據,數據還是在集合當中。Stream關注的是對數據的運算
②Stream 不會改變源對象。相反,會返回一個持有結果的新Stream。即Stream具有不可變的特性
③Stream 操作是延遲執行的。(一個操作代表着一個方法,可以理解爲每次調完之後就點一下,去調用方法,比如:過濾.映射.)對於中間操作來說,只要沒有調用終止操作,中間操作都不執行,只有調用終止操作纔會把中間操作都執行,也就是說是延遲執行的。這意味着會等到需要結果的時候才執行

Stream要想進行一些操作,要分成三個步驟
Stream操作的三個步驟
1) 創建 Stream的對象
一個數據源(如:集合、數組),獲取一個流
根據數據源得到對應的Stream
2) 中間操作
一箇中間操作鏈(即可以有多箇中間操作),對數據源的數據進行處理
3) 終止操作(終端操作)
一旦執行終止操作,就執行中間操作鏈,併產生結果,如果不執行終止操作,中間操作鏈就不會執行。一旦產生結果以後就終止了,當前的Stream對象就不能再去點中間操作了,之後,不會再被使用。也就是說如果再想使用,又要從頭再造Stream

Stream的實例化:

public class StreamAPITest {
    //創建 Stream方式一:通過集合
    //Java8中的Collection接口被擴展,提供了兩個獲取流的方法:
    //default Stream<E> stream() : 返回一個順序流
    //default Stream<E> parallelStream() : 返回一個並行流
    @Test
    public void test1(){
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();//接口的默認方法要通過接口的實現類的對象去調用
        //順序流:拿數據會按照集合中的順序來

        System.out.println("***************************************");

        Stream<Employee> parallelStream = employees.parallelStream();
        //並行流:會同時的去取數據
    }


    //因爲數組也是一種容器,所以還可以通過數組
    //創建 Stream方式二:通過數組
    //調用Arrays的 static <T> Stream<T> stream(T[] array): 返回一個流
    @Test
    public void test2(){
        int[] arr=new int[]{1,2,3,4,5,6};

        IntStream stream = Arrays.stream(arr);//因爲我們給的是int[],所以返回的是IntStream
        // public static DoubleStream stream(double[] array)其他的基本類型同理
        //如果扔進去的是自定義類型數組,那麼返回的就是Stream<自定義類型名>

        Employee e1=new Employee(1001,"Tom");
        Employee e2=new Employee(1002,"jerry");

        Employee[] arr1=new Employee[]{e1,e2};//這是靜態初始化
        Stream<Employee> stream1 = Arrays.stream(arr1);//類型是通過Stream的泛型體現的


    }

    //創建Stream方式三:通過Stream的of()
    //of中可以寫多個值,相當於構成一個容器,Stream對象就可以操作這個容器
    @Test
    public void test3(){

        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);//是看做包裝類的對象

    }

    //創建 Stream方式四:創建無限流(用的比較少,瞭解即可,前面對應的多個數據都是有限的)
    //這裏創建的是無限個元素對應的Stream
    @Test
    public void test4(){
        //迭代 public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //注意:UnaryOperator是函數式接口

        //遍歷前10個偶數
        //0是初始值,返回的是t+2,但注意返回的t+2又會繼續迭代,就會不停地加2,就不止10個了
        //想看效果要用到終止操作forEach(),裏面要填Consumer,而println就是典型的放東西進去不出東西的例子
        //也可以寫成Lambda表達式的形式,而下面是直接寫成方法引用
        Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);//第二個參數繼承了Function,Function是函數式接口,它是特殊的Function,一般的Function是T和R,而這個東西的apply方法放進去和返回的東西的類型都是T
        //上面的東西會一直輸出,是停不下來的,所以確實是無限流,可以加上限制limit(10)只要前十個,這個東西也是中間操作




        // 生成 public static<T> Stream<T> generate(Supplier<T> s)
        //Supplier是不往裏面放東西還出東西,典型的就是Math的random方法,因爲這個方法是靜態方法,所以要通過類來調用
        //輸出10個隨機數
        Stream.generate(Math::random).limit(10).forEach(System.out::println);

    }
}

輸出結果爲:

0
2
4
6
8
10
12
14
16
18
0.7994332036259181
0.8757405751180581
0.4900134823715929
0.5749140464545273
0.147323475304579
0.8053550561631083
0.4990720011692096
0.8312497979827275
0.9049172841130427
0.7791026058049584
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章