1. 程式人生 > 其它 >【Java29】Stream流

【Java29】Stream流

技術標籤:Javastreamfilterjava

文章目錄


1.Stream流引入

package com.itheima07.boot;
import java.util.ArrayList;
import java.util.List;
// 程式碼冗餘: 1. 迴圈太多 2. 判斷太多
public class StreamBootDemo {
    public static void main(String[] args) {
        List<
String>
list = new ArrayList<>(); list.add("張無忌"); list.add("周芷若"); list.add("趙敏"); list.add("張強"); list.add("張三丰"); //張集合 List<String> zhangList = new ArrayList<>(); for
(String name : list) { if (name.startsWith("張")) { zhangList.add(name); } } //短集合 : 張集合基礎上,只要名字3個 List<String> shortList = new ArrayList<>(); for (String name : zhangList) { if (name.length() == 3
) { shortList.add(name); } } for (String name : shortList) { //遍歷列印 System.out.println(name); } } }

在這裡插入圖片描述

package com.itheima07.boot;
import java.util.ArrayList;
import java.util.List;
// Stream 流: 1. 基於函數語言程式設計延伸出來的一種用法。 2. 作用: 簡化 集合資料 處理過程中的程式碼冗餘問題
public class StreamBootDemo02 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("張無忌");
        list.add("周芷若");
        list.add("趙敏");
        list.add("張強");
        list.add("張三丰");        
        list.stream().filter(name -> name.startsWith("張")) //name就是集合中的每個元素
                .filter(name -> name.length() == 3).forEach(name-> System.out.println(name));
    }
}

2.Stream流的獲取

在這裡插入圖片描述
如下排除靜態方法,ArrayList能用stream方法的話,是從Collection裡繼承這方法
在這裡插入圖片描述

package com.itheima08.stream;
import com.sun.org.apache.bcel.internal.generic.NEW;
import java.util.*;
import java.util.stream.Stream;
/*
*   Stream 流: Stream流物件的獲取:
*         1. 集合
*             Collection介面 預設方法 stream()
*         2. 陣列
*           Stream.of(T...);  使用這個
*           Stream.of(T);
*/
public class StreamGetDemo {
    public static void main(String[] args) {
        Collection<String> coll = new HashSet<>();
        Stream<String> stream = coll.stream();

//1111111111111111111111111111111111111111111111111111111111111111111111111111
        HashMap<String, String> map = new HashMap<>();
//        Set set = map.keySet();
//        set.stream();
        Stream<String> stream1 = map.keySet().stream();
        Stream<Map.Entry<String, String>> stream2 = map.entrySet().stream();
        
//111111111111111111111111111111111111111111111111111111111111111111111111111
        String[] array = {"a","b"};
        Stream<String> stream3 = Stream.of(array);
        
        Integer[] array2 = {1,2,3};
        Stream<Integer> stream4 = Stream.of(array2); //T...  -> T=Integer,把每個元素拆開。//泛型 必須是 引用型別
        
        int[] array3 = {1,2,3};
        //如果說陣列要獲取Stream流,不要用基本型別陣列, 把整個陣列當成一個元素無法拆開,不要用如下
        Stream<int[]> stream5 = Stream.of(array3);// T -> T = int[]
    }
}

3.Stream流的終結方法

package com.itheima09.method;     
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
/*
* Stream流的方法
*   1. 終結方法 : 不支援鏈式程式設計 (返回值: 基本型別)
*   2. 拼接方法 : 支援鏈式程式設計 (返回值: 當前型別,引用型別)
* 
*     終結方法:
*           1.foreach
*                   void forEach(Consumer<? super T> action);
*                   底層: 迭代器 , 需要消費引數(集合中每一個元素)
*           2.count
*                   long count() : 獲取集合中的元素個數
*/
public class EndDemo {
    public static void main(String[] args) {
//        method();
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 5,3,2,4);
//        for (Integer integer : list) { //list.for快捷
//            System.out.println(integer); 
//        }

//11111111111111111111111111111111111111111111111111111111111111111111  
		//stream流列印,先獲取stream流物件
       /* list.stream().forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer t) {
                System.out.println(t); //遍歷列印list集合
            }
        });*/
        
		//如下等於上面
//      list.stream().forEach(t-> System.out.println(t));

//11111111111111111111111111111111111111111111111111111111111111111111
        long count = list.stream().count();
        System.out.println(count); //4
    }
    
    private static void method() {
       // StringBuilder sb = new StringBuilder();
       // StringBuilder sb2 = sb.append("a");
       // StringBuilder sb3 = sb2.append("b"); 
        StringBuilder sb = new StringBuilder();
       //append拼接方法,equals終結方法,因為equals返回boolean基本型別,不能再呼叫方法
        sb.append("a").append("b").append("c").equals("abc");
    }
}

4.Stream流的拼接方法

package com.itheima09.method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.function.Predicate;
import java.util.stream.Stream;
/*
*   Stream的拼接方法
*       1. filter 過濾
*            Stream<T> filter(Predicate<? super T> predicate);
*               1. Predicate : public boolean test(String s)
*               2. s是集合中每一個元素 , 迭代器
*               3. return true : 表示保留這個元素
*       2. limit 取用前幾個
*              Stream<T> limit(long count)
*              只要前count個元素, 沒有越界
*       3. skip 跳過前幾個
*           Stream<T> skip(long n);
*       4. static concat 組合,靜態方法
*           static <T> Stream<T> concat(Stream<T> a, Stream< T> b)
*           合併兩個stream,整合一個stream
*/
public class ChainDemo { //Chain:鏈
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"張三","張三丰","李四","李世石");
        
		//.filter返回值型別是stream,調完filter還能調filter,就像Stringbuild調完append還可再調append
//        list.stream().filter(new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return s.startsWith("張");
//            }
//        }).forEach(s -> System.out.println(s)); //張三 張三丰

//        list.stream().filter(s->s.startsWith("張")).forEach(s-> System.out.println(s)); //等同上面

//        list.stream().limit(5).forEach(t-> System.out.println(t)); //沒有索引越界,因為迭代器沒有索引,最多4個就給4個

//        list.stream().skip(3).forEach(t-> System.out.println(t)); //李世石

        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,"王五","王五百","馬六");
        Stream<String> stream1 = list.stream();
        Stream<String> stream2 = list2.stream();
        Stream.concat(stream1,stream2).forEach(t-> System.out.println(t)); //張三...7個元素
    }
}

5.Stream原始碼分析

package com.itheima10.source;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Predicate;
  
public class MyStream {
    Collection<String> coll; //屬性
    public MyStream(Collection<String> coll){
        this.coll = coll;
    }
    
    public void forEach(Consumer<String> consumer){
        for (String s : coll) { //快捷鍵coll.foreach
            consumer.accept(s); //介面呼叫方法執行子類重寫的方法即下面SourceDemo.java中System.out.println(t),s就是t,
        }
    }
    
    public MyStream filter(Predicate<String> predicate){        
        ArrayList<String> list = new ArrayList<>(); //list集合只新增 推斷結果true的元素,新的
        for (String s : coll) {
            boolean result = predicate.test(s); //父類引用呼叫方法執行子類重寫方法即下面SourceDemo.java中t.length()==2
            if(result){
                list.add(s);
            }
        }
        coll = list;  //集合重置為list即保留下來的集合
        return this;
    }
}
package com.itheima10.source;
import java.util.ArrayList;
import java.util.Collections;

public class SourceDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"張三","李四光","王五");
        /*
        *  foreach:
        *    1. 迭代器(底層)
        *    2. t是集合中的每一個元素
        *    執行次數 = 集合元素個數
        */        
       // new MyStream(list).forEach(t -> System.out.println(t));

        /*
        *   MyStream filter(Predicate<String> predicate)
        *       predicate :  boolean test(T t);
        *       1. 迭代器
        *       2. t 是集合中的每一個元素
        *       3. 返回true : 表示保留這個元素
        */
        new MyStream(list).filter(t -> t.length()==2).forEach(t-> System.out.println(t));
    }
}

在這裡插入圖片描述

6.綜合案例

package com.itheima11.union;
import java.util.ArrayList;
import java.util.List;

public class Demo01 {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("迪麗熱巴");
        one.add("宋遠橋");
        one.add("蘇星河");
        one.add("老子");
        one.add("莊子");
        one.add("孫子");
        one.add("洪七公");
        List<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("張無忌");
        two.add("張三丰");
        two.add("趙麗穎");
        two.add("張二狗");
        two.add("張天愛");
        two.add("張三");       
        List<String> oneA = new ArrayList<>();  // 第一個隊伍只要名字為3個字的成員姓名;
        for (String name : one) {
            if (name.length() == 3) {
                oneA.add(name);
            }
        }        
        List<String> oneB = new ArrayList<>(); // 第一個隊伍篩選之後只要前3個人;
        for (int i = 0; i < 3; i++) {
            oneB.add(oneA.get(i));
        }

//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111             
        List<String> twoA = new ArrayList<>(); // 第二個隊伍只要姓張的成員姓名;
        for (String name : two) {
            if (name.startsWith("張")) {
                twoA.add(name);
            }
        }        
        List<String> twoB = new ArrayList<>(); // 第二個隊伍篩選之後不要前2個人;
        for (int i = 2; i < twoA.size(); i++) {
            twoB.add(twoA.get(i));
        }

//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111                   
        List<String> totalNames = new ArrayList<>(); // 將兩個隊伍合併為一個隊伍;
        totalNames.addAll(oneB);
        totalNames.addAll(twoB);                
        for (String name : totalNames) { // 列印整個隊伍的姓名資訊。
            System.out.println(name);
        }
    }
}
package com.itheima11.union;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Demo02 {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("迪麗熱巴");
        one.add("宋遠橋");
        one.add("蘇星河");
        one.add("老子");
        one.add("莊子");
        one.add("孫子");
        one.add("洪七公");
        List<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("張無忌");
        two.add("張三丰");
        two.add("趙麗穎");
        two.add("張二狗");
        two.add("張天愛");
        two.add("張三");
//stream流式程式設計核心:隱藏了沒有必要的迴圈迭代,把最核心的條件暴露出來並通過鏈式程式設計方式把程式碼順起來
//        1. 第一個隊伍只要名字為3個字的成員姓名;
//        2. 第一個隊伍篩選之後只要前3個人;
        Stream<String> stream1 = one.stream().filter(s -> s.length() == 3).limit(3);
//        3. 第二個隊伍只要姓張的成員姓名;
//        4. 第二個隊伍篩選之後不要前2個人;
        Stream<String> stream2 = two.stream().filter(s -> s.startsWith("張")).skip(2);
//        5. 將兩個隊伍合併為一個隊伍;
//        6. 列印整個隊伍的姓名資訊。
        Stream.concat(stream1,stream2).forEach(t-> System.out.println(t));
    }
}

B站/知乎/微信公眾號:碼農程式設計錄
在這裡插入圖片描述