您好,登錄后才能下訂單哦!
本文以jdk8中stream為例,為大家分析stream的函數以及函數的使用方法,并介紹了stream的特性。閱讀完整文相信大家對jdk8中的stream有了一定的認識。
日常中對于數據的篩選是非常普通的操作了,以前通常都會放在數據庫篩選或者自己寫方法進行篩選。
獲取某些行數據,一行就搞定。
List<SysUser> users = mapper.getAllUsers();
// 獲取指定id的用戶
List<SysUser> targetUsers = users.stream().filter(u->ids.contains(u.getId())).collect(Collectors.toList());
// .collect(Collectors.toList()):可以根據需要換成其他集合
該操作的作用就是將input Stream的每一個元素,按照一定規則處理之后,映射成output Stream的另一個元素,相當于一對一的輸入輸出,平時該方式使用較多。
比如說:
List<SysUser> users = mapper.getAllUsers();
// 把名字轉換成大寫;
List<SysUser> targetUsers = users.stream().map(u->u.getName().toUpperCase()).collect(Collectors.toList());
顧名思義,用于轉換流類型的方法。這個沒有什么可說的。
這個操作方法被稱作:平鋪,我理解的更像是集合的合并操作。看下面的例子。
Stream<List<Integer>> inputStream = Stream.of(
Arrays.asList(1),
Arrays.asList(2, 3),
Arrays.asList(4, 5, 6)
);
Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
List<Integer> list = outputStream.collect(Collectors.toList());
System.out.println(list);
// [1,2,3,4,5,6]
將二維轉成了一維。
比較簡單,可能需要注意的是,不能修改自己包含的本地變量值,也不能使用 break/return 之類的關鍵字提前結束循環。
獲取第一個元素。但沒有獲取第二個、第三個、最后一個元素的函數方法。
這個方法的作用主要是把Stream中的元素組合起來,比如說字符串拼接,數值類型的求和等都是特殊的reduce操作,并且我們可以根據重載方法選擇是否有初始值。
// 字符串連接,concat = "ABCD"
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
// 求最小值,minValue = -3.0
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
// 求和,sumValue = 10, 有起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
// 求和的另一種形式
int sum = Stream.of(1, 2, 3, 4).reduce(0, (a,b) -> a+b);
// 求和,sumValue = 10, 無起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
// 過濾,字符串連接,concat = "ace"
concat = Stream.of("a", "B", "c", "D", "e", "F")
.filter(x -> x.compareTo("Z") > 0)
.reduce("", String::concat);
reduce方法可以結合filter,map進行各種復合操作,是我們非常常用的方法。也是我們需要掌握和理解的方法。
limit是取流前n個元素,skip是跳過前m個元素剩余的元素,這兩個方法有點像用來做分頁用的。在mongodb操作內存數據時經常會使用到這些方法。
進行排序,默認的自然排序規則進行排序, 也可以指定具體的比較器來進行排序。
List<Integer> list = Arrays.asList(5, 7, 1, 4, 2, 6, 3, 8, 9, 10);
list.stream().limit(5).sorted().forEach(System.out::print);
System.out.println();
list.stream().limit(5).sorted(Comparator.reverseOrder()).forEach(System.out::print);
Stream中的findAny、max/min、reduce等方法等返回Optional值。還有例如IntStream.average()返回OptionalDouble等等.這里比較重點的是Optional的返回值類型,Optional:這也是一個模仿 Scala 語言中的概念,作為一個容器,它可能含有某值,或者不包含,使用它的目的是盡可能避免NullPointerException。
// Optional 的兩個用例
// Java 8
Optional.ofNullable(message).ifPresent(System.out::println);
// Pre-Java 8
if (message != null) {
System.out.println(message);
}
// Java 8
return Optional.ofNullable(message).map(String::length).orElse(-1);
// Pre-Java 8
return if (message != null) ? message.length() : -1;
};
使用Optional代碼的可讀性更好,而且它提供的是編譯時檢查,能極大的降低NPE這種Runtime Exception 對程序的影響,或者迫使程序員更早的在編碼階段處理空值問題,而不是留到運行時再發現和調試。
Stream 的特性可以歸納為:
1.不是數據結構;
2.它不做內部存儲,它只是用操作管道從source(數據結構、數組、generator function、IO channel)抓取數據;
3.它也絕不修改自己所封裝的底層數據結構的數據。例如Stream的filter操作會產生一個不包含被過濾元素的新Stream,而不是從source刪除那些元素;
4.所有Stream的操作必須以lambda表達式為參數;不支持索引訪問;
5.你可以請求第一個元素,但無法請求第二個,第三個,或最后一個;
6.惰性化:到具體使用才會進行操作;很多Stream操作是向后延遲的,一直到它弄清楚了最后需要多少數據才會開始;
7.Intermediate操作永遠是惰性化的;
8.當一個 Stream 是并行化的,就不需要再寫多線程代碼,所有對它的操作會自動并行進行的;
9.可以是無限的。集合有固定大小,Stream 則不必。limit(n)和findFirst()這類的short-circuiting操作可以對無限的Stream進行運算并很快完成。
以上就是jdk8中stream的函數和特性的詳細內容了,看完之后是否有所收獲呢?小編相信有部分知識點可能是我們日常工作可能會見到或用到的。希望你能通過這篇文章學到更多知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。