这篇文章主要介绍“Java8中Stream的使用方式是什么”,在日常操作中,相信很多人在Java8中Stream的使用方式是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java8中Stream的使用方式是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
性能优势,(大数据量)相较于迭代器,速度更快
支持串行与并行处理,并行处理更能充分利用CPU的资源
Stream 是一种计算数据的流,它本身不会存储数据
支持函数式编程
代码优雅,让代码更高效,干净,简洁
三步操作:
创建Stream
中间操作
终止操作
Stream
的 创建都会依赖于数据源,通常是容器或者数组 Stream
流的创建大致分为4中,最为常用的就是通过集合创建
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 通过集合创建Stream也是用的最多的一种形式
List<String> strList = new ArrayList<>();
strList.add("a");
strList.add("b");
strList.add("c");
// 创建串行操作流
Stream<String> stream = strList.stream();
// 创建并行操作流
Stream<String> parallelStream = strList.parallelStream();
// 2 通过数组创建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 无限流
// 每隔五个数取一个
Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代
Stream.generate(Math::random).forEach(System.out::println); // 生成
}
}
Stream
中间操作,我们最为常用的就是过滤,去重,排序 本章包含我们开发最常用的对对象的去重,和更据对象中的对个属性组合排序
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);
// 去重
// 对对象去重是根据引用去重,内容重复并不会去重,除非重写equals和hashCode方法
System.out.println("----------去重----------");
System.out.println("去重1----------");
students.stream().distinct().forEach(System.out::println);
// 对集合中对象某些属性去重,不重写equals和hashCode方法,只能借助其他数据结构来辅助去重
// 单个属性可以stu -> stu.getId()
// 多个属性可以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 默认使用 自然序排序, 其中的元素必须实现Comparable 接口
System.out.println("----------排序----------");
System.out.println("排序1----------");
students.stream().sorted().forEach(System.out::println);
// sorted(Comparator<? super T> comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。
System.out.println("排序2----------");
students.stream()
.sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序
.forEach(System.out::println);
// 创建比较器,通过对比较器内容的定义实现对多个属性进行排序,类似sql中连续的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);
// 截取 截取前三个元素
System.out.println("----------截取----------");
students.stream().limit(3).forEach(System.out::println);
// 跳过 跳过前3个元素
System.out.println("----------跳过----------");
students.stream().skip(3).forEach(System.out::println);
// 映射
System.out.println("----------映射----------");
System.out.println("映射Map----------");
// map接收Lambda,将元素转换其他形式,或者是提取信息,并将其映射成一个新的元素
Stream<Stream<Student>> streamStream1 = students.stream().map(str -> filterStudent(str));
streamStream1.forEach(sm -> sm.forEach(System.out::println));
System.out.println("映射flatMap----------");
// map接收Lambda,将流中的每一个元素转换成另一个流,然后把所有流连成一个流 扁平化映射
Stream<Student> studentStream2 = students.stream().flatMap(str -> filterStudent(str));
studentStream2.forEach(System.out::println);
// 消费
System.out.println("----------消费----------");
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
的终止操作,最常用的就是讲处理过的数据收集到新的容器中,同时可以实现向Sql聚合函数,分组的一些效果
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:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10);
System.out.println("全部符合大于10岁条件:" + allMatch);
// noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10);
System.out.println("全部不符合大于10岁条件:" + noneMatch);
// anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20);
System.out.println("含有任意符合大于20岁条件:" + anyMatch);
// findFirst:返回流中第一个元素
Student findFirst = students.stream().findFirst().get();
System.out.println("第一个学生:" + findFirst);
// findAny:返回流中的任意元素
Student findAny = students.stream().findAny().get();
System.out.println("任意一个学生:" + findAny);
// count:返回流中元素的总个数
long count = students.stream().count();
System.out.println("学生总数:" + count);
// max:返回流中元素最大值
Student max = students.stream().max(Student::compareTo).get();
System.out.println("年龄最大学生:" + max);
// max:返回流中元素最大值
Student min = students.stream().min(Student::compareTo).get();
System.out.println("年龄最小学生:" + min);
System.out.println("--------------------规约操作--------------------");
System.out.println("学生年龄总和:" + students.stream().map(Student::getAge).reduce(Integer::sum));
System.out.println("学生年龄最大:" + 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(",", "(", ")"));
// 总数
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);
//多重分组,先根据性别分再根据年龄分
Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
//分区
//分成两部分,一部分大于20岁,一部分小于等于20岁
Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20));
//规约
Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get();
System.out.println(allAge);
}
}
中间操作惰性执行
多个中间操作的话,不会多次循环,多个转换操作只会在终止操作的时候融合起来,一次循环完成。
内部迭代
找到符合条件的数据后边的迭代不会进行
流的末端操作只有一次
异常:stream has already been operated upon or closed
意思是流已经被关闭了,这是因为当我们使用末端操作之后,流就被关闭了,无法再次被调用,如果我们想重复调用,只能重新打开一个新的流。
到此,关于“Java8中Stream的使用方式是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。