概述
Stream的操作步骤
1 创建流(数据源)
2 中间操作(不会执行任何操作)
3 终止操作(一次性执行全部操作,即惰性求值)
Stream的创建
1 通过Collection系列集合提供的stream()
或parallelstream()创建一个并行流
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
Stream<String> stream = list.parallelStream();
2 通过Arrays 中的静态方法stream()获取数组流
Integer[] array = {1,2,3};
Stream<Integer> stream2 = Arrays.stream(array);
3 通过stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa", "bb");
4 创建无限流
4.1迭代按照一个一元运算规则产生一个无限流
Stream.iterate(0, (x) -> x + 2)
.limit(10)
.forEach(System.out::println);
4.2 生成一个无限流
Stream.generate(() ->Math.random())
.limit(4)
.forEach(System.out::println);
中间操作
筛选与切片
1 filter 接收lambda 从流中排除某些元素
students.stream()
//中间操作,不会执行任何操作
//从流中过滤出年龄>18 的元素对象
.filter(s -> s.getAge()>18
//终止操作,一次性执行全部内容,即惰性求值
.forEach(System.out::println);
2 limit 截断流 ,使其元素不超过给定数量
students.stream()
.filter(s -> s.getAge()>18)
//取前两个元素
.limit(2)
.forEach(System.out::println);
3 skip 跳过元素返回一个扔掉前n个元素的流,
若流中的元素不足n个则返回一个空流,与limit(n)互补
students.stream()
.filter(s -> s.getAge()>18)
.skip(2)
.forEach(System.out::println);
4 distinct 筛选,通过流所生成的hashcode()和equals(),去除重复元素
students.stream()
.distinct()
.forEach(System.out::println);
中间操作映射
1 map 接收 lambda将元素转换成其他形式,或提取信息
接收一个函数作为参数,该函数会应用到每个元素上
并将其映射为一个新的元素
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
//将元素一一映射到此函数上str.toUpperCase()并产生一个新流
list.stream()
.map((str) -> str.toUpperCase())
.forEach(System.out::println);
//map 做提取 提取员工的名字
students.stream()
.map(Student::getName)
.forEach(System.out::println);
2 flatMap 接收一个函数作为参数,将流中的每一个值都换成 另一个流,
然后把所有流连接成一个流
案例:对给定单词列表 [“Hello”,“World”],你想返回列表[“H”,“e”,“l”,“o”,“W”,“r”,“d”]
方式一
String[] words = new String[]{"Hello","World"};
List<String[]> a = Arrays.stream(words)
.map(word -> word.split(""))
.distinct()
.collect(toList());
a.forEach(System.out::print);
代码输出为:
[Ljava.lang.String;@12edcd21
[Ljava.lang.String;@34c45dca
(返回一个包含两个String[]的list)
这个实现方式是由问题的,传递给map方法的lambda
为每个单词生成了一个String[]
map返回的流实际上是Stream<String[]> 类型的。
你真正想要的是用Stream<String>来表示一个字符串。
方式二 对流扁平化处理
String[] words = new String[]{"Hello","World"};
List<String> a = Arrays.stream(words)
.map(word -> word.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(toList());
a.forEach(System.out::print);
使用flatMap方法的效果是,各个数组并不是分别映射一个流,
而是映射成流的内容,
所有使用flatmap(Array::stream)时生成的单个流被合并起来
即扁平化为一个流
中间操作排序
1 自然排序
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
list.stream()
.sorted()
.forEach(System.out::println);
2 定制排序
students.stream()
.sorted((s1,s2) ->{
if (s1.getAge().equals(s2.getAge())){
return s1.getName().compareTo(s2.getName());
}else {
return -s1.getAge().compareTo(s2.getAge());
}
}).forEach(System.out::println);
终止操作
查找与匹配
1 allMatch 检查是否匹配所有元素
//匹配所有元素 ,年龄是不是18
boolean b = students.stream()
.allMatch((s) -> s.getAge() == 18);
System.out.println(b);
2 anyMatch 检查是否至少匹配一个元素
boolean b1 = students.stream()
.anyMatch((s) -> s.getName().equals("张三"));
System.out.println(b1);
3 noneMatch 检查是否没有匹配的元素
boolean b2 = students.stream()
.noneMatch(s -> s.getAge() == 50);
System.out.println(b2);
4 findFirst 返回第一个元素
java8 对空指针进行优化
把我们的结果封装到Optional对象中
可有效避免空指针
//排序后取第一个
Optional<Student> op = students.stream()
.sorted((s1, s2) -> -Double.compare(s1.getSalary(), s2.getSalary()))
.findFirst();
System.out.println(op.get());
5 findAny 找满足条件的任意一个
//找满足条件的任意一个
//parallelStream()并行流多个线程去找
Student student = students.parallelStream()
.filter(s -> s.getAge() < 20)
.findAny().get();
System.out.println(student);
6 count 返回流中元素总个数
//获取流中元素总数
long count = students.stream()
.count();
System.out.println(count);
7 max 返回流中最大值
//获取最高工资
Student student = students.stream()
.max((s1, s2) -> Double.compare(s1.getSalary(), s2.getSalary()))
.get();
System.out.println(student);
//获取最高工资是多少
Double max = students.stream()
.map(Student::getSalary)
.max(Double::compareTo)
.get();
System.out.println(max);
8 min 返回流中最小值
//获取最小工资是多少方式1
Double salary = students.stream()
.min((s1, s2) -> Double.compare(s1.getSalary(), s2.getSalary()))
.get().getSalary();
System.out.println(salary);
//方式2
Double minSalary = students.stream()
.map(Student::getSalary)
.min(Double::compareTo)
.get();
System.out.println(minSalary);
规约
reduce(T identity,BinaryOperator)
reduce(BinaryOperator)
将流中元素结合起来返回一个值
List<Integer> list = Arrays.asList(1,2,4,5,6);
Integer sum = list.stream()
.reduce(0, (x, y) -> x + y);
System.out.println(sum);
//计算工资总和
//map reduce 模式 提取 归约
Double salarySum = students.stream()
.map(Student::getSalary)
.reduce(Double::sum)
.get();
System.out.println(salarySum);
收集
收集 将流转换成其他形式
接收一个Collector接口实现
用于给stream中元素做汇总的方法
//把所有名字提取出来 放到一个list集合中去
students.stream()
.map(Student::getName)
.collect(Collectors.toList())
.forEach(System.out::println);
//将流转换成hashset
students.stream()
.map(Student::getName)
.collect(Collectors.toCollection(HashSet::new))
.forEach(System.out::println);