1、如何理解Stream
Java8新特性
Stream可以理解为管道,管道里的流水就是数据,管道里可以对水进行处理,如过滤,消毒,净化等等操作。最后流出的水才能喝。
所以我理解Stream关注的是对数据的加工计算。对比java集合框架,集合框架关注的是如何存取数据。
一个stream操作主要有3个部分:源头、中间操作、终止操作。
中间操作可以有0个或多个 但不是立马执行的,只有终止操作被调用后中间操作才会一起执行(惰性执行)
有了stream操作后 会简化我们的操作,如循环
如循环一个数组,打印,如下操作,而非原来的for循环,是否很简洁
int[] intArray = new int[]{2,4,6,1}; Arrays.stream(intArray).forEach(System.out::println);
2、Stream来源
stream主要来源:数组 集合
数组:
int[] intArray = new int[]{2,4,6,1}; Arrays.stream(intArray).forEach(System.out::println); Stream.of(intArray).forEach(System.out::println);
集合Collection
strList.stream().forEach(System.out::println); Stream.of(strList).forEach(System.out::println);
3、中间操作
主要有filter map flatmap sorted skip limit distinct
例:
public static void main(String[] args) { List<String> strList = Arrays.asList("yy","ff","dd","11","12","##"); strList.stream().filter(x->x.matches("^\\w.*")). map(x->x+"end").sorted().skip(1).limit(2).distinct().forEach(System.out::println); }
输出:
12end
ddend
主要说明下flatmap 这个是把流的每个元素映射为一个stream ,再把所有的stream连到一起(扁平化操作),例:
strList.stream().flatMap(x->Stream.of(x.split(","))).forEach(System.out::println);
每次中间操作都会产生一个新的stream
4、终止操作
主要有:
reduce,foreach,collect
allMatch,anyMatch,noneMatch
findFirst,findAny
max,min,count
例:
import java.util.*; import java.util.stream.Collectors; class StreamMode{ private String name; private int age; public StreamMode(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "StreamMode{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class StreamYf { public static void main(String[] args) { List<StreamMode> strList = new ArrayList<>(); StreamMode streamMode1 = new StreamMode("y1",21); StreamMode streamMode2 = new StreamMode("y3",22); StreamMode streamMode3 = new StreamMode("y2",23); StreamMode streamMode4 = new StreamMode("y4",20); StreamMode streamMode5 = new StreamMode("y5",19); strList.add(streamMode1); strList.add(streamMode2); strList.add(streamMode3); strList.add(streamMode4); strList.add(streamMode5); //map reduce(lamdba需要两个参数) Optional<Integer> reduce = strList.stream().map(StreamMode::getAge).reduce(Integer::sum); System.out.println(reduce.get()); //allMatch 全部匹配 (anyMatch noneMatch用法一样) boolean resultAllMatch = strList.stream().allMatch(x -> x.getAge() > 20); System.out.println("resultAllMatch="+resultAllMatch); //findFirst找出排序后的第一个元素(降序即从大到小) Optional<StreamMode> firstEle = strList.stream().sorted(Comparator.comparingInt(StreamMode::getAge).reversed()).findFirst(); System.out.println("firstEle="+firstEle.get()); //findAny找出任一个元素 Optional<StreamMode> anyEle = strList.stream().findAny(); System.out.println("anyEle="+anyEle.get()); //找出最大的元素 min类似 Optional<Integer> maxAge = strList.stream().map(StreamMode::getAge).max(Integer::max); System.out.println("maxAge="+maxAge.get()); //统计过滤后元素的个数 long count = strList.stream().filter(x -> x.getAge() > 20).count(); System.out.println("count="+count); //collect 收集后转为List toSet类似用法 List<Integer> collectList = strList.stream().map(StreamMode::getAge).collect(Collectors.toList()); System.out.println("collectList="+collectList); //collect 收集后转为Map Map<String, List<StreamMode>> collectMap = strList.stream().collect(Collectors.groupingBy(StreamMode::getName)); System.out.println("collectMap="+collectMap); //collect 收集后求平均年龄 sum max 类似 Double collectAvg = strList.stream().collect(Collectors.averagingInt(StreamMode::getAge)); System.out.println("collectAvg="+collectAvg); //collect 获取SummaryStatistics 可以一次性获取max min sum等 IntSummaryStatistics collectAll = strList.stream().collect(Collectors.summarizingInt(StreamMode::getAge)); System.out.println("collectAvg2="+collectAll.getAverage()); System.out.println("collectCount2="+collectAll.getCount()); } }
5、并发stream
paralleStream基于ForkJoin(把大任务拆为多个子任务计算再合并)可以实现并行stream
并非线程安全 慎用