您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java8中Stream的使用方式是什么”,在日常操作中,相信很多人在Java8中Stream的使用方式是什么問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Java8中Stream的使用方式是什么”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
性能優(yōu)勢(shì),(大數(shù)據(jù)量)相較于迭代器,速度更快
支持串行與并行處理,并行處理更能充分利用CPU的資源
Stream 是一種計(jì)算數(shù)據(jù)的流,它本身不會(huì)存儲(chǔ)數(shù)據(jù)
支持函數(shù)式編程
代碼優(yōu)雅,讓代碼更高效,干凈,簡(jiǎn)潔
三步操作:
創(chuàng)建Stream
中間操作
終止操作
Stream
的 創(chuàng)建都會(huì)依賴于數(shù)據(jù)源,通常是容器或者數(shù)組 Stream
流的創(chuàng)建大致分為4中,最為常用的就是通過集合創(chuàng)建
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; public class CreateStreamDemo { public static void main(String[] args) { // 1 通過集合創(chuàng)建Stream也是用的最多的一種形式 List<String> strList = new ArrayList<>(); strList.add("a"); strList.add("b"); strList.add("c"); // 創(chuàng)建串行操作流 Stream<String> stream = strList.stream(); // 創(chuàng)建并行操作流 Stream<String> parallelStream = strList.parallelStream(); // 2 通過數(shù)組創(chuàng)建Stream int[] arr = new int[]{1,2,3}; IntStream intStream = Arrays.stream(arr); // 3 通過Stream.of Stream<Integer> integerStream = Stream.of(1,2,3); Stream<String> stringStream = Stream.of("a","b","c"); // 4 無限流 // 每隔五個(gè)數(shù)取一個(gè) Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代 Stream.generate(Math::random).forEach(System.out::println); // 生成 } }
Stream
中間操作,我們最為常用的就是過濾,去重,排序 本章包含我們開發(fā)最常用的對(duì)對(duì)象的去重,和更據(jù)對(duì)象中的對(duì)個(gè)屬性組合排序
import com.zhj.java8.bean.Student; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet; import java.util.stream.Stream; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toCollection; public class MiddleStreamDemo { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1,"小華",23,1)); students.add(new Student(1,"小華",23,2)); students.add(new Student(2,"小米",20,2)); students.add(new Student(3,"小果",30,3)); students.add(new Student(4,"小維",18,2)); // 過濾 students.stream().filter(stu -> stu.getAge() > 20).forEach(System.out::println); // 去重 // 對(duì)對(duì)象去重是根據(jù)引用去重,內(nèi)容重復(fù)并不會(huì)去重,除非重寫equals和hashCode方法 System.out.println("----------去重----------"); System.out.println("去重1----------"); students.stream().distinct().forEach(System.out::println); // 對(duì)集合中對(duì)象某些屬性去重,不重寫equals和hashCode方法,只能借助其他數(shù)據(jù)結(jié)構(gòu)來輔助去重 // 單個(gè)屬性可以stu -> stu.getId() // 多個(gè)屬性可以stu -> stu.getId() + ";" + stu.getName() System.out.println("去重2----------"); ArrayList<Student> distinctList = students.stream().collect( collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new) ); distinctList.stream().forEach(System.out::println); // 排序 支持定義排序方式 // sorted 默認(rèn)使用 自然序排序, 其中的元素必須實(shí)現(xiàn)Comparable 接口 System.out.println("----------排序----------"); System.out.println("排序1----------"); students.stream().sorted().forEach(System.out::println); // sorted(Comparator<? super T> comparator) :我們可以使用lambada 來創(chuàng)建一個(gè)Comparator 實(shí)例。可以按照升序或著降序來排序元素。 System.out.println("排序2----------"); students.stream() .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序 .forEach(System.out::println); // 創(chuàng)建比較器,通過對(duì)比較器內(nèi)容的定義實(shí)現(xiàn)對(duì)多個(gè)屬性進(jìn)行排序,類似sql中連續(xù)的orderBy System.out.println("排序3----------"); students.stream().sorted( (s1,s2) -> { if (s1.getAge() == s2.getAge()) { return s1.getSex().compareTo(s2.getSex()); } else { return -s1.getAge().compareTo(s2.getAge()); } } ).forEach(System.out::println); System.out.println("排序4----------"); Comparator<Student> studentComparator = (s1,s2) -> { Integer age1 = s1.getAge(); Integer age2 = s2.getAge(); if (age1 != age2) return age1 - age2; Integer sex1 = s1.getSex(); Integer sex2 = s2.getSex(); if (sex1 != sex2) return sex2 - sex1; return 0; }; students.stream().sorted(studentComparator).forEach(System.out::println); // 截取 截取前三個(gè)元素 System.out.println("----------截取----------"); students.stream().limit(3).forEach(System.out::println); // 跳過 跳過前3個(gè)元素 System.out.println("----------跳過----------"); students.stream().skip(3).forEach(System.out::println); // 映射 System.out.println("----------映射----------"); System.out.println("映射Map----------"); // map接收Lambda,將元素轉(zhuǎn)換其他形式,或者是提取信息,并將其映射成一個(gè)新的元素 Stream<Stream<Student>> streamStream1 = students.stream().map(str -> filterStudent(str)); streamStream1.forEach(sm -> sm.forEach(System.out::println)); System.out.println("映射flatMap----------"); // map接收Lambda,將流中的每一個(gè)元素轉(zhuǎn)換成另一個(gè)流,然后把所有流連成一個(gè)流 扁平化映射 Stream<Student> studentStream2 = students.stream().flatMap(str -> filterStudent(str)); studentStream2.forEach(System.out::println); // 消費(fèi) System.out.println("----------消費(fèi)----------"); students.stream().peek(stu -> stu.setAge(100)).forEach(System.out::println); } public static Stream<Student> filterStudent(Student student) { student = new Student(); return Stream.of(student); } }
Student
public class Student implements Comparable<Student> { private Integer id; private String name; private Integer age; private Integer sex; public Student() { } public Student(Integer id, String name, Integer age, Integer sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } @Override public String toString() { return "Student{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age='" + age + '\'' + ", sex=" + sex + '}'; } @Override public int compareTo(Student o) { return this.getAge() - o.getAge(); } }
Stream
的終止操作,最常用的就是講處理過的數(shù)據(jù)收集到新的容器中,同時(shí)可以實(shí)現(xiàn)向Sql聚合函數(shù),分組的一些效果
package com.zhj.java8.stream; import com.zhj.java8.bean.Student; import java.util.*; import java.util.stream.Collectors; public class TerminationStreamDemo { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student(1,"小華",23,1)); students.add(new Student(2,"小米",20,2)); students.add(new Student(3,"小果",30,3)); students.add(new Student(4,"小維",18,2)); students.add(new Student(5,"小華",23,2)); System.out.println("--------------------匹配聚合操作--------------------"); // allMatch:接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都符合該斷言時(shí)才返回true,否則返回false boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10); System.out.println("全部符合大于10歲條件:" + allMatch); // noneMatch:接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都不符合該斷言時(shí)才返回true,否則返回false boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10); System.out.println("全部不符合大于10歲條件:" + noneMatch); // anyMatch:接收一個(gè) Predicate 函數(shù),只要流中有一個(gè)元素滿足該斷言則返回true,否則返回false boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20); System.out.println("含有任意符合大于20歲條件:" + anyMatch); // findFirst:返回流中第一個(gè)元素 Student findFirst = students.stream().findFirst().get(); System.out.println("第一個(gè)學(xué)生:" + findFirst); // findAny:返回流中的任意元素 Student findAny = students.stream().findAny().get(); System.out.println("任意一個(gè)學(xué)生:" + findAny); // count:返回流中元素的總個(gè)數(shù) long count = students.stream().count(); System.out.println("學(xué)生總數(shù):" + count); // max:返回流中元素最大值 Student max = students.stream().max(Student::compareTo).get(); System.out.println("年齡最大學(xué)生:" + max); // max:返回流中元素最大值 Student min = students.stream().min(Student::compareTo).get(); System.out.println("年齡最小學(xué)生:" + min); System.out.println("--------------------規(guī)約操作--------------------"); System.out.println("學(xué)生年齡總和:" + students.stream().map(Student::getAge).reduce(Integer::sum)); System.out.println("學(xué)生年齡最大:" + students.stream().map(Student::getAge).reduce(Integer::max)); System.out.println("--------------------收集操作--------------------"); List<Student> list = students.stream().collect(Collectors.toList()); Set<Student> set = students.stream().collect(Collectors.toSet()); Map<Integer, String> map = students.stream().collect(Collectors.toMap(Student::getId, Student::getName)); String joinName = students.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // 總數(shù) students.stream().collect(Collectors.counting()); // 最大年齡 students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 年齡和 students.stream().collect(Collectors.summingInt(Student::getAge)); // 平均年齡 students.stream().collect(Collectors.averagingDouble(Student::getAge)); // 信息合集 DoubleSummaryStatistics statistics = students.stream().collect(Collectors.summarizingDouble(Student::getAge)); System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage()); // 分組 Map<Integer, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSex)); System.out.println(collect); //多重分組,先根據(jù)性別分再根據(jù)年齡分 Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge))); //分區(qū) //分成兩部分,一部分大于20歲,一部分小于等于20歲 Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20)); //規(guī)約 Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); System.out.println(allAge); } }
中間操作惰性執(zhí)行
多個(gè)中間操作的話,不會(huì)多次循環(huán),多個(gè)轉(zhuǎn)換操作只會(huì)在終止操作的時(shí)候融合起來,一次循環(huán)完成。
內(nèi)部迭代
找到符合條件的數(shù)據(jù)后邊的迭代不會(huì)進(jìn)行
流的末端操作只有一次
異常:stream has already been operated upon or closed
意思是流已經(jīng)被關(guān)閉了,這是因?yàn)楫?dāng)我們使用末端操作之后,流就被關(guān)閉了,無法再次被調(diào)用,如果我們想重復(fù)調(diào)用,只能重新打開一個(gè)新的流。
到此,關(guān)于“Java8中Stream的使用方式是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。