【java代碼之美】---Java8 Stream

來源:互聯網
上載者:User

標籤:首字母排序   常用   字元   流水線   license   array   基本類型   特殊   list()   

Stream

第一次看到Stream運算式就深深把我吸引,用它可以使你的代碼更加整潔而且對集合的操作效率也會大大提高,如果你還沒有用到java8的Stream特性,那就說明你確實out啦。

一、概述1、什麼是Stream

Stream是一種可供流式操作的資料檢視有些類似資料庫中視圖的概念它不改變來源資料集合如果對其進行改變的操作它會返回一個新的資料集合。

總的來講它有三大特性:在之後我們會對照著詳細說明

       1、stream不儲存資料

       2、stream不改變來源資料

       3、stream的順延強制特性

2、Stream優點
  1. 代碼簡潔,函數式編程寫出的代碼簡潔且意圖明確,使用stream介面讓你從此告別for迴圈。

  2. 多核友好,Java函數式編程使得編寫並行程式從未如此簡單,你需要的全部就是調用一下parallel()方法。

3、Stream API常用方法
Stream操作分類
中間操作(Intermediate operations) 無狀態(Stateless) unordered() filter() map() mapToInt() mapToLong() mapToDouble() flatMap() flatMapToInt() flatMapToLong() flatMapToDouble() peek()
有狀態(Stateful) distinct() sorted() sorted() limit() skip()
結束操作(Terminal operations) 非短路操作 forEach() forEachOrdered() toArray() reduce() collect() max() min() count()
短路操作(short-circuiting) anyMatch() allMatch() noneMatch() findFirst() findAny()

 

 

 

 

 

 

 

 

 

Stream上的所有操作分為兩類:中間操作和結束操作,中間操作只是一種標記,只有結束操作才會觸發實際計算。

中間操作又可以分為無狀態的和有狀態的:

      無狀態中間操作是指元素的處理不受前面元素的影響,而有狀態的中間操作必須等到所有元素處理之後才知道最終結果,比如排序是有狀態操作,在讀取所有元素之前並不能確定排序結果;

結束操作又可以分為短路操作和非短路操作

      短路操作是指不用處理全部元素就可以返回結果,比如找到第一個滿足條件的元素。之所以要進行如此精細的劃分,是因為底層對每一種情況的處理方式不同。

常用中介軟體

      filter:過濾流,過濾流中的元素,返回一個合格Stream

      map:轉換流,將一種類型的流轉換為另外一種流。(mapToInt、mapToLong、mapToDouble 返回int、long、double基本類型對應的Stream)

 flatMap:簡單的說,就是一個或多個流合并成一個新流。(flatMapToInt、flatMapToLong、flatMapToDouble 返回對應的IntStream、LongStream、DoubleStream流。)

 distinct:返回去重的Stream。

  sorted:返回一個排序的Stream。

    peek:主要用來查看流中元素的資料狀態。

     limit:返回前n個元素資料群組成的Stream。屬於短路操作

     skip:返回第n個元素後面資料群組成的Stream。 

結束操作

  forEach: 迴圈操作Stream中資料。

  toArray: 返迴流中元素對應的數組對象。

  reduce: 彙總操作,用來做統計。

  collect: 彙總操作,封裝目標資料。

min、max、count: 彙總操作,最小值,最大值,總數量。

   anyMatch: 短路操作,有一個符合條件返回true。

    allMatch: 所有資料都符合條件返回true。

noneMatch: 所有資料都不符合條件返回true。

    findFirst: 短路操作,擷取第一個元素。

     findAny: 短路操作,擷取任一元素。

forEachOrdered: 暗元素順序執行迴圈操作。

 

二、各種案例說明

多舉點例子,以後忘記了還可以來找自己的部落格,哈哈。

首先寫一個領域對象

public class Person {        private Integer  id;        private String name;        private String sex;        private Integer age;        //提供get,set,和滿參建構函式}
1、map中介軟體相關例子
public class TestMap {        public static void main(String[] args) {        List<Person> persionList = new ArrayList<Person>();        persionList.add(new Person(1,"張三","男",8));        persionList.add(new Person(2,"小小","女",2));        persionList.add(new Person(3,"李四","男",25));        persionList.add(new Person(4,"王五","女",20));        persionList.add(new Person(5,"趙六","男",38));        persionList.add(new Person(6,"大大","男",65));            //1、只取出該集合中所有姓名組成一個新集合        List<String> nameList=persionList.stream().map(Person::getName).collect(Collectors.toList());        System.out.println(nameList.toString());        //2、只取出該集合中所有id組成一個新集合          List<Integer> idList=persionList.stream().mapToInt(Person::getId).boxed().collect(Collectors.toList());         System.out.println(idList.toString());        //3、list轉map,key值為id,value為Person對象         Map<Integer, Person> personmap = persionList.stream().collect(Collectors.toMap(Person::getId, person -> person));         System.out.println(personmap.toString());          //4、list轉map,key值為id,value為name         Map<Integer, String> namemap = persionList.stream().collect(Collectors.toMap(Person::getId, Person::getName));         System.out.println(namemap.toString());             }}

 運行結果:

是不是之前要好幾層的for迴圈解決的問題,通過Stream只要一行代碼就可以解決了。

這裡要注意,如果你list轉map的key如果不唯一,會報錯,所以如果你不確定你的key是否唯一,可以改成如下:

 Map<Integer, String> map = persionList.stream().collect(                Collectors.toMap(Person::getAge, Person::getName, (key1, key2) -> key1)        );
 2、filter相關例子
public class TestFilter {    public static void main(String[] args) {        List<Person> persionList = new ArrayList<Person>();        persionList.add(new Person(1, "張三", "男", 8));        persionList.add(new Person(2, "小小", "女", 2));        persionList.add(new Person(3, "李四", "男", 25));        persionList.add(new Person(4, "王五", "女", 8));        persionList.add(new Person(5, "趙六", "女", 25));        persionList.add(new Person(6, "大大", "男", 65));        //1、尋找年齡大於20歲的人數        long  age=persionList.stream().filter(p->p.getAge()>20).count();        System.out.println(age);        //2、尋找年齡大於20歲,性別為男的人數       List<Person>  ageList=persionList.stream().filter(p->p.getAge()>20).filter(p->"男".equals(p.getSex())).collect(Collectors.toList());        System.out.println(ageList.size());    }    /*     *運行結果:     *  3     *  2     */}
 3、sorted相關例子

   對於數組舉例

public class TestSort {    String[] arr1 = {"abc","a","bc","abcd"};    /**     * 按照字元長度排序     */    @Test    public void testSorted1_(){        Arrays.stream(arr1).sorted(Comparator.comparing(String::length)).forEach(System.out::println);        //輸出:a、bc、abc、abcd    }    /**     * 倒序     * reversed(),java8泛型推導的問題,所以如果comparing裡面是非方法引用的lambda運算式就沒辦法直接使用reversed()     * Comparator.reverseOrder():也是用於翻轉順序,用於比較對象(Stream裡面的類型必須是可比較的)     * Comparator. naturalOrder():返回一個自然排序比較子,用於比較對象(Stream裡面的類型必須是可比較的)     */    @Test    public void testSorted2_(){        Arrays.stream(arr1).sorted(Comparator.comparing(String::length).reversed()).forEach(System.out::println);        //輸出:abcd、abc、bc、a        Arrays.stream(arr1).sorted(Comparator.reverseOrder()).forEach(System.out::println);        //輸出:bc、abcd、abc、a        Arrays.stream(arr1).sorted(Comparator.naturalOrder()).forEach(System.out::println);        //輸出:a、abc、abcd、bc    }    /**     * 先按照首字母排序     * 之後按照String的長度排序     */    @Test    public void testSorted3_(){        Arrays.stream(arr1).sorted(Comparator.comparing(this::com1).thenComparing(String::length)).forEach(System.out::println);    }
//輸出:a、abc、abcd、bc public char com1(String x){ return x.charAt(0); }}

 對於集合舉例

public class TestSort {    public static void main(String[] args) {        List<Person> persionList = new ArrayList<Person>();        persionList.add(new Person(1, "張三", "男", 8));        persionList.add(new Person(2, "小小", "女", 2));        persionList.add(new Person(3, "李四", "男", 25));        persionList.add(new Person(4, "王五", "女", 8));        persionList.add(new Person(5, "趙六", "女", 25));        persionList.add(new Person(6, "大大", "男", 65));        //1、找到年齡最小的歲數        Collections.sort(persionList, (x, y) -> x.getAge().compareTo(y.getAge()));        Integer age = persionList.get(0).getAge();        System.out.println("年齡最小的有:" + age);        //輸出:年齡最小的有:2        //2、找到年齡最小的姓名        String name = persionList.stream()                .sorted(Comparator.comparingInt(x -> x.getAge()))                .findFirst()                .get().getName();        System.out.println("年齡最小的姓名:" + name);        //輸出:年齡最小的姓名:小小    }}

 其它的就不具體寫了。以後遇到特殊的再往裡面補充。

 

參考

    1、跟上 Java 8 – Stream API 快速入門

   2、java8之stream

   3、[Java進階篇][函數式編程][Java 8+ Stream API]

   4、深入理解Java Stream流水線

 

想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多做。中校【10】 

【java代碼之美】---Java8 Stream

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.