JAVA--高級基礎開發

day09[Stream 流,方法引用]

第一章: Stream流java

這裏的 Stream,是在 Java 8 中,由於 Lambda 帶來的函數式編程,引入的一個全新的 Stream 概念,用於解決已有集合中既有的弊端。算法

    1. 概述
  1. 傳統集合的遍歷代碼,幾乎全部的集合(Collection,Map 等)都支持間接或直接的遍歷操做,而當咱們須要對集合中的元素進行操做的時候,除了必需的添加、刪除、獲取外,最典型的就是集合的遍歷。

//傳統的寫法編程

public class Test1{數組

    public static void main(String[] args) {數據結構

        ArrayList<String>list=new ArrayList<>();app

        list.add("李文傑");函數式編程

        list.add("李文集");函數

        list.add("李文潔");spa

        list.add("王智雅");對象

        list.add("何舒雅");

        list.add("王文文");

        //傳統的寫法

        for(String  ss:list){

          System.out.println(ss);

            }

        }

這是一段很是簡單的集合遍歷操做,集合中的字符串都進行輸出操做

    1. for循環遍歷的弊端
  1. 爲何使用循環?由於要進行遍歷,但循環是遍歷的惟一方式嗎?遍歷是指每個元素逐一進行處理,而並非從第一個到最後一個順次處理的循環,前者是目的,後者是方式。
  2. 試想一下,若是但願對集合中的元素進行篩選過濾:
  3. 一、將集合 A 根據條件過濾爲子集合 B
  4. 二、而後在根據條件過濾爲子集合 C

Java jdk8 以前的代碼:

 

public class Test1{

    public static void main(String[] args) {

        ArrayList<String>list=new ArrayList<>();

        list.add("李文傑");

        list.add("李文集");

        list.add("李文潔");

        list.add("王智雅");

        list.add("何舒雅");

        list.add("王文文");

        ArrayList<String>li=new ArrayList<>();

        //傳統的寫法

        for(String  ss:list){

            if(ss.startsWith("李")){

                li.add(ss);

            }

        }

        for(String  ss2: li){

            System.out.println(ss2);

        }

}

}

分析這段代碼中兩個 for 循環:

一、 首先篩選全部姓李的人

二、 而後存入到新的集合中

三、 最後進行篩選結果的輸出

每當咱們須要對集合中的元素進行操做的時候,老是須要進行循環,循環,再循環。循環只 是作事的方式而不是目的,另外一方面,使用線性循環就意味着只能遍歷一次,若是但願再次

遍歷,只能在執行一次代碼。

  • Lambda 的衍生物 Stream 能給我帶來更加優雅簡潔的寫法

Stream流的優雅寫法

//體驗Stream 流

public class Test1{

    public static void main(String[] args) {

        ArrayList<String>list=new ArrayList<>();

        list.add("李文傑");

        list.add("李文集");

        list.add("李文潔");

        list.add("王智雅");

        list.add("何舒雅");

        list.add("王文文");

//使用Stream 流輸出

        list.stream().filter(s->s.startsWith("")).

filter(s->s.length()==3).forEach(s->System.out.println(s));

//foreach 表明的就是for循環

    }

}

總結爲: 獲取流,過濾流,過濾流,開頭爲李,長度爲 3,逐一輸出,代碼中並無體現使用線性循環或其餘任何算法進行遍歷。

    1. 流式思想的概述
  • 總體來看,流式思想相似於工廠車間的「生產流水線」。
  • Stream 流其實就是一個集合元素的函數模型,它並非集合,也不是數據結構,其自己也不存儲任何元素。
  1. Stream 流是一個來自數據源的元素隊列。
  • 元素是特定類型的對象,造成一個隊列,java 中的 Stream 流不存儲元素,而是按需計算。
  • 數據域流的來源,能夠是集合、數組等。
  • 當使用一個流的時候,一般包括三個基本步驟:
  • 獲取一個數據源-->數據轉換,執行操做獲取想要的結果,每次轉換原有 Stream 流對象不改變,返回一個新的 Stream 對象,這就容許對其操做能夠像鏈條同樣排列,造成一個管道。
    1. 獲取流Stream
  1. 位於java.util.stream 包中,interface Stream<T>接口是 Java 8 新加入的最經常使用的流接口(這並非一個函數式接口)
  1. List集合 Set集合 數組獲取流的方法:
  2. 獲取一個流很是簡單,有如下幾種經常使用方式:
  3. 全部的 Collection 集合(List,Set)均可以經過 stream 默認方法獲取流。
  4. Stream 接口的靜態方法 of 能夠獲取數組對應的流.

//Collection 集合獲取Stream流

public class Test2 {

    public static void main(String[] args) {

 //List集合獲取流

        List<String>list=new ArrayList<>();

        Stream<String>listStream=list.stream();

 

        //Set集合獲取流

        Set<String>set=new HashSet<>();

        Stream<String>setStream=set.stream();

 

        //數組獲取流Stream

        String[]array={"13","34","65","76","23"};

        Stream<String>stream=Stream.of(array);

    }

}

  1. 根據Map集合獲取流:
  • java.util.Map 接口不是 Collection 的子接口,其 K-V 數據結構不符合流元素的單一特徵,因此獲取對應的流須要分 key、value 或 entry 等狀況。

//Map集合獲取流Stream流

public class Test2 {

public static void main(String[] args) {

//Map集合獲取流

        Map<String,String>map=new HashMap<>();

        //Map集合Stream流獲取鍵

        Stream<String>mapStream=map.keySet().stream();

        //Map集合Stream流獲取值

        Stream<String>maps=map.values().stream();

        //Map集合經過EntrySet來獲取Stream流,獲得鍵和值

        Stream<Map.Entry<String,String>>entry=map.entrySet().stream();

}

}

 

    1. 經常使用的方法
  1. 延遲方法:返回值類型任然是一個 Stream 對象,所以支持鏈式調用(除了終結方法以

外,其他方法都是延遲方法) 

  1. 終結方法:返回值類型再也不是 Stream 接口,所以再也不支持鏈式調用。

1.6  Foreach

  1. 雖然名字叫foreach,可是與加強的for循環不一樣。

void  forEach(Consumer<? super T> action) d

該方法接收一個Consumer接口的函數,會將每個流元素交給函數進行處理

基本使用:

public class Test3 {

    public static void main(String[] args) {

        //foreach示例

        Stream<String>stream=Stream.of("李文傑","張文集","王蘭君","李軍帽");

         stream.forEach(s -> System.out.println(s));

    }

}

1.7  Filter

過濾:能夠經過Filter方法將一個流轉換爲另外一個流

Stream<T> filter(Predicate<? super T> predicate) 

該方法接收一個 Predicate 函數式接口參數

基本使用:

public class Test3 {

    public static void main(String[] args) {

          //Fifter過濾器

Stream<String>stream=Stream.of("李文傑","張文集","王蘭君","李軍帽");

        Stream<String>newstream=stream.filter(s ->s.startsWith("李"));

        newstream.forEach(s -> System.out.println(s));

    }

}

 

1.8  map映射

1 若是須要將流中的元素映射到另外一個流中,可使用 map 方法.

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

基本使用:

public class Test3 {

    public static void main(String[] args) {

        //map映射

        Stream<String>stream1=Stream.of("12","34","45","66","99");

        Stream<Integer>stream2=stream1.map(s ->Integer.parseInt(s));

        stream2.forEach(s-> System.out.println(s+10));

}

}

1.9 count 統計個數

流經過count方法來計算流中的個數

long  count(); 返回此流中的元素數。

基本使用

//count方法的使用。

public class Test3 {

 public static void main(String[] args) {

//count方法來統計流的個數

        Stream<String>stream3=Stream.of("劉備","張飛","臥龍","鳳雛");

        System.out.println("統計流的個數:"+stream3.count());

}

}

2.0  Limit 提取前幾個元素

Limit 方法能夠對流進行截取,只取前n個。

Stream<T> limit(long maxSize) 

基本使用:

public class Test3 {

public static void main(String[] args) {

//limit方法使用,對流進行截取

      Stream<String>stream4=Stream.of("趙雲","關羽","黃忠","馬超");

        Stream<String>stream5=stream4.limit(3);

        stream5.forEach(s -> System.out.println(s));

    }

}

2.1 Skip 跳過前幾個元素

Skip方法能夠對流實現跳過的操做,繼續執行如下的數據

Stream<T> skip (long n) ;

若是流的當前長度大於 n,則跳過前 n 個,不然將會獲得一個長度爲 0 的空流

基本使用:

public class Test3 {

public static void main(String[] args) {

//Skip方法實現對流元素的跳過

        Stream<String>stream5=Stream.of("趙雲","關羽","黃忠","馬超");

        Stream<String>stream6=stream5.skip(2);

        stream6.forEach(s -> System.out.println(s));

    }

}

2.2 concat組合

若是有兩個流,但願合併成爲一個流,那麼可使用 Stream 接口靜態方法 concat

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 

基本使用:

public class Test3 {

public static void main(String[] args) {

    //concat 若是兩個流,但願合併爲一個流,那麼就能夠進行組合

        Stream<String>stream7=Stream.of("馬超");

        Stream<String>stream8=Stream.of("西涼人");

        Stream<String>stream9=Stream.concat(stream7,stream8);

        stream9.forEach(s -> System.out.println(s));}

}

相關文章
相關標籤/搜索