Stream流

Stream流式思想概述

/**
 * 用傳統(tǒng)的方式,遍歷集合,對集合中的數(shù)據(jù)進(jìn)行過濾
 */
public class Demo10Stream {
    public static void main(String[] args) {
        //創(chuàng)建一個list集合,存儲姓名
        List<String> list = new ArrayList<>();
        list.add("張無忌");
        list.add("周芷若");
        list.add("趙敏");
        list.add("張墻");
        list.add("張三豐");
        //對list集合中的元素進(jìn)行排序,只要以張開頭的元素,存儲到一個新的集合中
        List<String> listA = new ArrayList<>();
        for(String s : list){
            if(s.startsWith("張")){
                listA.add(s);
            }

        }
        //對listA集合進(jìn)行過濾,只要姓名長度為3的人,存儲到一個新的集合中
        List<String> listB = new ArrayList<>();
        for(String s : listA){
            if(s.length() == 3){
                listB.add(s);
            }
        }
        //遍歷listB集合
        for(String s:listB){
            System.out.println(s);
        }
    }
}

import java.util.ArrayList;
import java.util.List;

/**
 * 用Stream流的方式,遍歷集合,對集合中的數(shù)據(jù)進(jìn)行過濾
 * Stream關(guān)注的是做什么,而不是怎么做
 */
public class Demo10Stream1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("張無忌");
        list.add("周芷若");
        list.add("趙敏");
        list.add("張墻");
        list.add("張三豐");
        //對list集合中的元素進(jìn)行排序,只要以張開頭的元素,存儲到一個新的集合中
        //對listA集合進(jìn)行過濾,只要姓名長度為3的人,存儲到一個新的集合中
        //遍歷listB集合
        list.stream()
                .filter(name->name.startsWith("張"))
                .filter(name->name.length()==3)
                .forEach(name-> System.out.println(name));//兩次過濾,一次輸出
    }
}

Stream流是一個來自數(shù)據(jù)源的元素隊(duì)列。
數(shù)據(jù)源可以是集合,數(shù)組等。
兩個基本特征:
(1)Pipelining:中件的操作都返回流本身,這樣多個操作可以串聯(lián)成一個管道。
(2)內(nèi)部迭代:以前對集合遍歷都是通過Iterator或增強(qiáng)for的方式,顯示的在集合外部進(jìn)行迭代,這叫外部迭代。Stream提供了內(nèi)部迭代的方式,流可以直接調(diào)用遍歷方法。
當(dāng)使用一個流的時候,通常包括三個基本步驟:獲取一個數(shù)據(jù)源-》數(shù)據(jù)轉(zhuǎn)換-》執(zhí)行操作獲取想要的結(jié)果,每次轉(zhuǎn)換原油Stream對象不改變,返回一個新的Stream對象(可以有多次轉(zhuǎn)換),這就允許對其操作可以像鏈條一樣排列,變成一個管道。

兩種獲取Stream流的方式

java.util.stream.Stream<T>是Java8新加入的最常用的流接口(并不是函數(shù)式接口)
(1)所有的Collection集合都可以通過stream默認(rèn)方法獲取流;
(2)stream接口的靜態(tài)方法of可以獲取數(shù)組對應(yīng)的流。

 public static void main(String[] args) {
        //把集合轉(zhuǎn)換為Stream流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        Set<String> set = new HashSet<>();
        Stream<String> stream2 = set.stream();

        Map<String, String> map = new HashMap<>();
        //獲取鍵,存儲到一個set集合中
        Set<String> keySet = map.keySet();
        Stream<String> stream3 = keySet.stream();
        //獲取值,存儲到一個Collection集合中
        Collection<String> values = map.values();
        Stream<String> stream4 = values.stream();
        //獲取鍵值對(鍵與值的映射關(guān)系entryset)
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Stream<Map.Entry<String, String>> stream5 = entries.stream();
        
        //把數(shù)組轉(zhuǎn)換為Stream流
        Stream<Integer> stream6 = Stream.of(1,2,3,4,5);
        //可變參數(shù)可以傳遞數(shù)組
        Integer[] arr = {1, 2, 3, 4, 5};
        Stream<Integer> stream7 = Stream.of(arr);
        String[] arr2 = {"a", "bb", "ccc"};
    }

常用方法:
方法被分為兩種:
(1)延遲方法:返回值類型仍然是Stream接口自身類型的方法,因此支持鏈?zhǔn)秸{(diào)用(除了終結(jié)方法外,其余方法均為延遲方法)。
(2)終結(jié)方法:返回值類型不再是Stream接口自身類型的方法,因此不再支持類似StringBuilder那樣的鏈?zhǔn)秸{(diào)用。終結(jié)方法包括count和forEach方法。

forEach方法:
import java.util.stream.Stream;

/**
 * forEach()接受一個Consumer接口函數(shù),是一個消費(fèi)型接口,可以傳遞lambda表達(dá)式,消費(fèi)數(shù)據(jù)
 * forEach方法用來遍歷流中的數(shù)據(jù),是一個終結(jié)方法,遍歷之后就不能繼續(xù)調(diào)用Stream流中的其他方法
 * */
public class Demo01ForEach {
    public static void main(String[] args) {
        //獲取Stream流
       Stream<String> stream = Stream.of("張三","李四","王五","趙六","田七");
        //使用Stream流中的方法forEach對Stream流中的數(shù)據(jù)進(jìn)行遍歷
        stream.forEach((String name)->{
            System.out.println(name);
        });
    }
}
filter方法:
import java.util.stream.Stream;

/**
 * Stream流中的常用方法filter:用于對Stream流中的數(shù)據(jù)進(jìn)行過濾
 * filter方法的參數(shù)Predicate是一個函數(shù)式接口,所以可以傳遞lambda表達(dá)式,對數(shù)據(jù)進(jìn)行過濾
 */
public class Demo02Filter {
    public static void main(String[] args) {
        //創(chuàng)建一個Stream流
        Stream<String> str = Stream.of("張三豐", "張翠山","趙敏","周芷若","張無忌");
        //對Stream流中的元素進(jìn)行過濾,只要姓張的人
        Stream<String> stream2 = str.filter((String name)->{return name.startsWith("張");});
        stream2.forEach(name -> System.out.println(name));
    }

}
/**
         * Stream流屬于管道流,只能被消費(fèi)(使用)一次
         * 第一個Stream流調(diào)用完畢方法,數(shù)據(jù)就會流轉(zhuǎn)到下一個Stream上,
         * 而這時第一個stream流已經(jīng)使用完畢,就會關(guān)閉了
         * 所以第一個Stream流就不能再調(diào)用方法了
         */
映射map方法:

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

import java.util.stream.Stream;

public class Demo03Stream_map {
    public static void main(String[] args) {
        //獲取一個String類型的Stream流
        Stream<String> stream = Stream.of("1", "2", "3", "4");
        //使用map方法,把字符串類型的整數(shù),轉(zhuǎn)換為Integer類型的整數(shù)
        Stream<Integer> stream2 = stream.map((String s)->{
            return Integer.parseInt(s);
        });
        //遍歷stream2流
        stream2.forEach(i-> System.out.println(i));
    }
}
count方法:

用于統(tǒng)計stream流中元素的個數(shù)
count方法是一個終結(jié)方法,返回值是一個long類型的整數(shù),所以不能再繼續(xù)調(diào)用Stream流中的其他方法了。

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        Stream<Integer> stream = list.stream();
        long count = stream.count();
        System.out.println(count);

    }
取用前幾個limit方法:
/**
 * limit是一個延遲方法,只是對流中的元素進(jìn)行截取,返回的是一個新的流,所以可以繼續(xù)調(diào)用Stream流中的其他方法
 */
public class Demo05Stream_limit {
    public static void main(String[] args) {
        //獲取一個Stream流
        String[] arr = {"美羊羊","喜洋洋","懶洋洋","灰太狼","紅太狼"};
        Stream<String> stream = Stream.of(arr);
        //使用limit對Stream流中的元素進(jìn)行截取,只要前三個元素
        Stream<String> stream2 = stream.limit(3);
        //遍歷stream2流
        stream2.forEach(name-> System.out.println(name));

    }
}
跳過前幾個skip方法:
      String[] arr = {"美羊羊","喜洋洋","懶洋洋","灰太狼","紅太狼"};
        Stream<String> stream = Stream.of(arr);
        //使用skip跳過前3個元素
        Stream<String> stream1 = stream.skip(3);
        stream1.forEach(name-> System.out.println(name));
    }
組合concat方法:
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Stream流 在Java 8中,得益于Lambda所帶 來的函數(shù)式編程,引入了一個全新的Stream概念,用于解...
    柒_wu7閱讀 658評論 0 0
  • 前言 這篇詳細(xì)介紹了Stream流的概念,創(chuàng)建方式,基本操作及部分源碼分析??赡苡悬c(diǎn)長哈,大家看起來比較費(fèi)勁,我自...
    秦老廝閱讀 967評論 1 2
  • 本文翻譯自 https://winterbe.com/posts/2014/07/31/java8-stream-...
    插件小屋閱讀 2,157評論 0 29
  • 由于最近一直在用scala寫spark程序,發(fā)現(xiàn)java8的流新特性跟scala幾乎一個思維,所以整理出來互相學(xué)習(xí)...
    __元昊__閱讀 796評論 0 3
  • 在馬來西亞我們一共待了4天半。我知道了很多事情,比如說華人很聰明,馬來人很笨,我給你們講一個故事就明白了。有一個華...
    2號小石頭王子貽閱讀 148評論 0 2

友情鏈接更多精彩內(nèi)容