成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Stream API有哪些中間操作?看完你也可以吊打面試官!!

開發 后端
多個中間操作可以連接起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全部處理,稱為“惰性求值” 。Stream的中間操作是不會有任何結果數據輸出的。

 作者個人研發的在高并發場景下,提供的簡單、穩定、可擴展的延遲消息隊列框架,具有精準的定時任務和延遲隊列處理功能。自開源半年多以來,已成功為十幾家中小型企業提供了精準定時調度方案,經受住了生產環境的考驗。為使更多童鞋受益,現給出開源框架地址:

https://github.com/sunshinelyz/mykit-delay

Stream的中間操作

多個中間操作可以連接起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全部處理,稱為“惰性求值” 。Stream的中間操作是不會有任何結果數據輸出的。

Stream的中間操作在整體上可以分為:篩選與切片、映射、排序。接下來,我們就分別對這些中間操作進行簡要的說明。

篩選與切片

這里,我將與篩選和切片有關的操作整理成如下表格。

 

接下來,我們列舉幾個簡單的示例,以便加深理解。

為了更好的測試程序,我先構造了一個對象數組,如下所示。

  1. protected List<Employee> list = Arrays.asList( 
  2.     new Employee("張三", 18, 9999.99), 
  3.     new Employee("李四", 38, 5555.55), 
  4.     new Employee("王五", 60, 6666.66), 
  5.     new Employee("趙六", 8, 7777.77), 
  6.     new Employee("田七", 58, 3333.33) 
  7. ); 

其中,Employee類的定義如下所示。

  1. @Data 
  2. @Builder 
  3. @ToString 
  4. @NoArgsConstructor 
  5. @AllArgsConstructor 
  6. public class Employee implements Serializable { 
  7.     private static final long serialVersionUID = -9079722457749166858L; 
  8.     private String name
  9.     private Integer age; 
  10.     private Double salary; 

Employee類的定義比較簡單,這里,我就不贅述了。之后的示例中,我們都是使用的Employee對象的集合進行操作。好了,我們開始具體的操作案例。

1.filter()方法

filter()方法主要是用于接收Lambda表達式,從流中排除某些元素,其在Stream接口中的源碼如下所示。

  1. Stream<T> filter(Predicate<? super T> predicate); 

可以看到,在filter()方法中,需要傳遞Predicate接口的對象,Predicate接口又是個什么鬼呢?點進去看下源碼。

  1. @FunctionalInterface 
  2. public interface Predicate<T> { 
  3.  
  4.     boolean test(T t); 
  5.  
  6.     default Predicate<T> and(Predicate<? super T> other) { 
  7.         Objects.requireNonNull(other); 
  8.         return (t) -> test(t) && other.test(t); 
  9.     } 
  10.  
  11.     default Predicate<T> negate() { 
  12.         return (t) -> !test(t); 
  13.     } 
  14.  
  15.     default Predicate<T> or(Predicate<? super T> other) { 
  16.         Objects.requireNonNull(other); 
  17.         return (t) -> test(t) || other.test(t); 
  18.     } 
  19.  
  20.     static <T> Predicate<T> isEqual(Object targetRef) { 
  21.         return (null == targetRef) 
  22.                 ? Objects::isNull 
  23.                 : object -> targetRef.equals(object); 
  24.     } 

可以看到,Predicate是一個函數式接口,其中接口中定義的主要方法為test()方法,test()方法會接收一個泛型對象t,返回一個boolean類型的數據。

看到這里,相信大家明白了:filter()方法是根據Predicate接口的test()方法的返回結果來過濾數據的,如果test()方法的返回結果為true,符合規則;如果test()方法的返回結果為false,則不符合規則。

這里,我們可以使用下面的示例來簡單的說明filter()方法的使用方式。

  1. //內部迭代:在此過程中沒有進行過迭代,由Stream api進行迭代 
  2. //中間操作:不會執行任何操作 
  3. Stream<Person> stream = list.stream().filter((e) -> { 
  4.     System.out.println("Stream API 中間操作"); 
  5.     return e.getAge() > 30; 
  6. }); 

我們,在執行終止語句之后,一邊迭代,一邊打印,而我們并沒有去迭代上面集合,其實這是內部迭代,由Stream API 完成。

下面我們來看看外部迭代,也就是我們人為得迭代。

  1. //外部迭代 
  2. Iterator<Person> it = list.iterator(); 
  3. while (it.hasNext()) { 
  4.     System.out.println(it.next()); 

2.limit()方法

主要作用為:截斷流,使其元素不超過給定數量。

先來看limit方法的定義,如下所示。

  1. Stream<T> limit(long maxSize); 

limit()方法在Stream接口中的定義比較簡單,只需要傳入一個long類型的數字即可。

我們可以按照如下所示的代碼來使用limit()方法。

  1. //過濾之后取2個值 
  2. list.stream().filter((e) -> e.getAge() >30 ).limit(2).forEach(System.out :: println); 

在這里,我們可以配合其他得中間操作,并截斷流,使我們可以取得相應個數得元素。而且在上面計算中,只要發現有2條符合條件得元素,則不會繼續往下迭代數據,可以提高效率。

3.skip()方法

跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素 不足 n 個,則返回一個空流。與 limit(n) 互補。

源碼定義如下所示。

  1. Stream<T> skip(long n); 

源碼定義比較簡單,同樣只需要傳入一個long類型的數字即可。其含義是跳過n個元素。

簡單示例如下所示。

  1. //跳過前2個值 
  2. list.stream().skip(2).forEach(System.out :: println); 

4.distinct()方法

篩選,通過流所生成元素的 hashCode() 和 equals() 去 除重復元素。

源碼定義如下所示。

  1. Stream<T> distinct(); 

旨在對流中的元素進行去重。

我們可以如下面的方式來使用disinct()方法。

  1. list.stream().distinct().forEach(System.out :: println); 

這里有一個需要注意的地方:distinct 需要實體中重寫hashCode()和 equals()方法才可以使用。

映射

關于映射相關的方法如下表所示。

 

1.map()方法

接收一個函數作為參數,該函數會被應用到每個元 素上,并將其映射成一個新的元素。

先來看Java8中Stream接口對于map()方法的聲明,如下所示。

  1. <R> Stream<R> map(Function<? super T, ? extends R> mapper); 

我們可以按照如下方式使用map()方法。

  1. //將流中每一個元素都映射到map的函數中,每個元素執行這個函數,再返回 
  2. List<String> list = Arrays.asList("aaa""bbb""ccc""ddd"); 
  3. list.stream().map((e) -> e.toUpperCase()).forEach(System.out::printf); 
  4.  
  5. //獲取Person中的每一個人得名字name,再返回一個集合 
  6. List<String> names = this.list.stream().map(Person :: getName).collect(Collectors.toList()); 

2.flatMap()

接收一個函數作為參數,將流中的每個值都換成另 一個流,然后把所有流連接成一個流。

先來看Java8中Stream接口對于flatMap()方法的聲明,如下所示。

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

我們可以使用如下方式使用flatMap()方法,為了便于大家理解,這里,我就貼出了測試flatMap()方法的所有代碼。

  1. /** 
  2.      * flatMap —— 接收一個函數作為參數,將流中的每個值都換成一個流,然后把所有流連接成一個流 
  3.      */ 
  4.     @Test 
  5.     public void testFlatMap () { 
  6.         StreamAPI_Test s = new StreamAPI_Test(); 
  7.         List<String> list = Arrays.asList("aaa""bbb""ccc""ddd"); 
  8.         list.stream().flatMap((e) -> s.filterCharacter(e)).forEach(System.out::println); 
  9.  
  10.         //如果使用map則需要這樣寫 
  11.         list.stream().map((e) -> s.filterCharacter(e)).forEach((e) -> { 
  12.             e.forEach(System.out::println); 
  13.         }); 
  14.     } 
  15.  
  16.     /** 
  17.      * 將一個字符串轉換為流 
  18.      */ 
  19.     public Stream<Character> filterCharacter(String str){ 
  20.         List<Character> list = new ArrayList<>(); 
  21.         for (Character ch : str.toCharArray()) { 
  22.             list.add(ch); 
  23.         } 
  24.         return list.stream(); 
  25.     } 

其實map方法就相當于Collaction的add方法,如果add的是個集合得話就會變成二維數組,而flatMap 的話就相當于Collaction的addAll方法,參數如果是集合得話,只是將2個集合合并,而不是變成二維數組。

排序

關于排序相關的方法如下表所示。

 

從上述表格可以看出:sorted有兩種方法,一種是不傳任何參數,叫自然排序,還有一種需要傳Comparator 接口參數,叫做定制排序。

先來看Java8中Stream接口對于sorted()方法的聲明,如下所示。

  1. Stream<T> sorted(); 
  2. Stream<T> sorted(Comparator<? super T> comparator); 

sorted()方法的定義比較簡單,我就不再贅述了。

我們也可以按照如下方式來使用Stream的sorted()方法。

  1. / 自然排序 
  2. List<Employee> persons = list.stream().sorted().collect(Collectors.toList()); 
  3.  
  4. //定制排序 
  5. List<Employee> persons1 = list.stream().sorted((e1, e2) -> { 
  6.     if (e1.getAge() == e2.getAge()) { 
  7.         return 0; 
  8.     } else if (e1.getAge() > e2.getAge()) { 
  9.         return 1; 
  10.     } else { 
  11.         return -1; 
  12.     } 
  13. }).collect(Collectors.toList()); 

寫在最后

如果覺得文章對你有點幫助,請微信搜索并關注「 冰河技術 」微信公眾號,跟冰河學習Java8新特性。

最后,附上Java8新特性核心知識圖,祝大家在學習Java8新特性時少走彎路。

本文轉載自微信公眾號「冰河技術」,可以通過以下二維碼關注。轉載本文請聯系冰河技術公眾號。

 

責任編輯:武曉燕 來源: 冰河技術
相關推薦

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2023-02-20 08:08:48

限流算法計數器算法令牌桶算法

2019-04-26 14:12:19

MySQL數據庫隔離級別

2021-09-26 10:57:16

集合操作場景

2021-09-27 06:50:04

非線性數據

2024-07-26 08:10:10

2021-08-20 08:33:19

操作系統OS

2025-03-26 01:25:00

MySQL優化事務

2024-03-07 17:21:12

HotSpotJVMHot Code

2025-06-04 07:48:46

2025-04-01 00:00:00

項目CRUD單例模式

2024-02-26 14:07:18

2021-05-10 08:01:12

BeanFactoryFactoryBean容器

2024-04-19 00:00:00

計數器算法限流算法

2024-03-12 14:36:44

微服務HTTPRPC

2015-08-13 10:29:12

面試面試官

2024-09-09 08:30:56

代碼

2022-02-14 20:53:33

開源庫開發代碼

2024-02-01 08:08:53

Spring過濾器類型Gateway

2021-08-11 08:53:23

Git命令面試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 夜夜夜久久久 | 久久一区| 成人av免费 | 伊人国产精品 | 国产第一亚洲 | 青青草原综合久久大伊人精品 | av中文网| 国产精品日日做人人爱 | 国产精品欧美精品日韩精品 | 欧美看片 | 国产精品视频久久久久久 | 国产欧美日韩在线播放 | 免费国产一区二区 | 一区二区精品视频 | 国产馆 | 91精品国产一区二区三区动漫 | 精品1区| 久久国产高清 | 欧美一区精品 | 天色综合网 | 91高清在线 | 日韩在线xx | 日日操夜夜操天天操 | 久久青| 国产乱码精品一区二区三区忘忧草 | 日韩一区二区精品 | 午夜在线| 一区二区福利视频 | 在线观看a视频 | 天堂中文字幕av | 亚洲视频免费播放 | 天堂av免费观看 | 免费成人在线网站 | 国产精品18hdxxxⅹ在线 | 中文字幕在线看第二 | 国产精品九九九 | 欧美极品视频在线观看 | 国产一区在线免费观看 | 亚洲性视频网站 | 精品久久久久久亚洲综合网 | 成人综合视频在线观看 |