创建Stream
1.可以通过Collection系列集合提供的stream()或parallelStream()
List<String> list = new ArrayList<String>();
Stream<String> stream = list.stream();
2.通过Arrays中的静态方法stream()获取数组流
String[] strings = new String[10];
Stream<String> stream2 = Arrays.stream(strings);
3.通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa", "bb", "cc");
4.创建无限流
// 方式一:迭代
// 以+2的方式迭代流
Stream<Integer> iterate = Stream.iterate(0, (x) -> x+2);
iterate.forEach(System.out::println);
// 方式二:生成
Stream.generate(() -> Math.random())
.limit(5)
.forEach(System.out::println);
用forEach结束流
// 惰性求值
List<Integer> list = Arrays.asList(11, 22, 33, 44, 55);
list.stream()
// 跳过前14个元素,若原集合元素不足14,则返回空流
.skip(14)
// 只取前四个,但如果集合是Set,顺序可能就是乱的
.limit(4)
// 从流中获取符合条件的元素
// filter内是断言型接口
.filter(e -> {
System.out.println("中间操作:" + e);
return true;
})
// 所有元素都满足条件时,返回true,否则返回false,括号内为断言型接口
.allMatch()
// 只要有一个元素满足条件,就返回true;否则,返回false
.anyMatch()
// 所有元素都不满足,返回true;否则,返回false
.noneMatch()
// 统计流中元素个数
.count()
// 括号内实现compare方法,默认为升序返回最大值
.max()
// 括号内实现compare方法,默认为升序返回最小值
.min()
// 最终返回一个值,括号内进行操作,然后返回一个值
.reduce()
// map括号内实现功能性接口,即要进行的操作
.map()
// 括号内为功能型接口的实现,返回一个流。该方法为将元素对应的小流全部填充到一个大流中
.flatMap()
// 元素去重
.distinct()
// 括号内要实现compare接口
.sorted( (e1, e2) -> Double.compare(e1.getSal(), e2.getSal()) )
.forEach(System.out::println);
System.out.println("Over");
reduce()方法案例
// 该写法返回值为Optional类型的
// 返回 封装了累计结果的 Optional
// 统计总工资
Optional<Double> reduce = Emp.getData().stream()
.map(Emp::getSal) // 提取出工资
.reduce((t, sal) -> {
// t: 前一次操作的结果
// sal: 当前遍历到的元素
System.out.println(t + "," + sal);
return t + sal;
});
System.out.println("reduce:" + reduce);
// 改写法返回到是初始值类型的
// 会根据 identity 进行初始的操作。identity 就是累计的起始值
// 会返回 指定的类型的值
Doublereduce2 = Emp.getData().stream()
.map(Emp::getSal) // 提取出工资
.reduce(100000D, (sum, sal) -> sum+sal);
System.out.println("reduce2:" + reduce2);
其他
1、在流中,如果不写终止操作,流的中间操作是不会执行的;只有当终止操作被加进来后,流的其他操作才会被执行(被称为惰性求值)
2、内部迭代由Stream API 完成,外部迭代由自己完成
3、distinct方法是通过流元素的hashCode()和equals()去重的,所以在必要时,要重写这两个方法