做著名建筑物网站简介,网站的栏目和板块设计,代发视频赚钱app,网站关键词排名外包stream相关api对于集合操作非常方便#xff0c;可以通过链式编程完成数据的处理#xff0c;有时候很复杂的数据处理通过使用stream的相关api可以非常方便的完成#xff0c;使用lambda表达式更可以简化为一行代码#xff0c;下面就介绍一下stream的相关api方法#xff0c;感…stream相关api对于集合操作非常方便可以通过链式编程完成数据的处理有时候很复杂的数据处理通过使用stream的相关api可以非常方便的完成使用lambda表达式更可以简化为一行代码下面就介绍一下stream的相关api方法感受一下如何使用。
一、构建stream操作流
构建stream流的方式有很多种比较常见的两种方式 一是通过集合的 .stream() 构建流或 .parallelStream() 构建并行流二是通过Stream类的相关api构建流。
通过集合的stream()或parallelStream()方法构建
ListInteger list new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
SetInteger set new HashSet(list);// 构建普通流
StreamInteger stream1 list.stream();
StreamInteger stream2 set.stream();// 构建并行流
StreamInteger pstream1 list.parallelStream();
StreamInteger pstream2 set.parallelStream();这里的并行流要注意它默认使用的是系统中的 ForkJoinPool.commonPool 线程池这个线程池默认大小是CPU核数如果要调整线程池大小可以有两种方法调整系统变量
System.setProperty(java.util.concurrent.ForkJoinPool.common.parallelism, 4);
或
-Djava.util.concurrent.ForkJoinPool.common.parallelism4添加一个打印逻辑验证处理线程名
pstream1.forEach(item - System.out.println(Thread.currentThread().getName() : item));没有添加上面的参数打印输出内容是
main : 7
main : 6
ForkJoinPool.commonPool-worker-18 : 2
ForkJoinPool.commonPool-worker-4 : 1
ForkJoinPool.commonPool-worker-18 : 10
main : 9
ForkJoinPool.commonPool-worker-4 : 4
ForkJoinPool.commonPool-worker-25 : 3
ForkJoinPool.commonPool-worker-11 : 8
ForkJoinPool.commonPool-worker-29 : 5添加配置后的输出内容
main : 7
main : 6
ForkJoinPool.commonPool-worker-1 : 3
ForkJoinPool.commonPool-worker-1 : 5
ForkJoinPool.commonPool-worker-2 : 9
ForkJoinPool.commonPool-worker-3 : 2
ForkJoinPool.commonPool-worker-1 : 4
ForkJoinPool.commonPool-worker-3 : 1
ForkJoinPool.commonPool-worker-0 : 8
ForkJoinPool.commonPool-worker-2 : 10可见配置参数确实调整了系统线程池的大小由于主线程也会参与计算所以对于计算密集型的服务线程池一般设置为CPU核数 - 1。
通过Stream的api构建 通过stream的api构建主要是Stream.of()方法构建
StreamInteger stream Stream.of(1, 2, 3, 4, 5, 6);
stream.forEach(System.out::println);对于特定类型的stream还有专门的api构建比如IntStream的range()和rangeClosed()方法构建一个范围内的数据其中range()方法包含开始数据不包含结束数据rangeClosed()方法包含开始数据同时包含结束数据。
// 包括开始不包括结束
System.out.println(----------------stream1----------------);
IntStream stream1 IntStream.range(1, 10);
stream1.forEach(System.out::println);// 包括开始和结束
System.out.println(----------------stream2----------------);
IntStream stream2 IntStream.rangeClosed(1, 10);
stream2.forEach(System.out::println);通过Arrays的stream()方法构建
int[] arr { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IntStream stream Arrays.stream(arr);
stream.forEach(System.out::println);上面就是几种常用的构建stream流方式使用stream流主要是处理数据处理数据又分为中间方法和终结方法它们的主要区别就是中间方法处理完后还可以继续使用stream流进行接下来的处理而终结方法执行后的流不能继续使用要想继续使用就必须重新开启一个流再次执行。 下面所有的流使用的都是这个stream做演示
ListInteger list new ArrayList(Arrays.asList(3, 6, 10, 5, 5, 2, 6, 4, 9, 7, 8, 1, 8, 9));
StreamInteger stream list.stream();二、中间方法
中间方法执行后获取到的仍然是一个可以使用的流常用的中间方法如下
过滤数据filter()
// 筛选大于3且小于8的数据
stream.filter(new PredicateInteger() {Overridepublic boolean test(Integer i) {return i 3 i 8;}
}).forEach(item - System.out.println(item));// lambda表达式
stream.filter(i - i 3 i 8).forEach(System.out::println);选择一个区间的数据skip()是跳过的数据条数limit()是返回的数据条数
// 跳过前2条数据返回5条数据
stream.skip(2).limit(5).forEach(System.out::println);数据去重distinct()
stream.distinct().forEach(System.out::println);数据排序sorted()
// 默认排序是升序排列
stream.sorted().forEach(System.out::println);// 自定义排序降序排列
stream.sorted(new ComparatorInteger() {Overridepublic int compare(Integer o1, Integer o2) {return o1 o2 ? -1 : (o1.intValue() o2.intValue() ? 0 : 1);}
}).forEach(item - System.out.println(item));// lambda表达式
stream.sorted((o1, o2) - o1 o2 ? -1 : (o1.intValue() o2.intValue() ? 0 : 1)).forEach(System.out::println);修改数据类型map()
stream.map(new FunctionInteger, String() {Overridepublic String apply(Integer i) {return i- i;}
}).forEach(item - System.out.println(item));// lambda表达式
stream.map(i - i- i).forEach(System.out::println);修改数据类型flatMap()
stream.flatMap((FunctionInteger, Stream?) num - {// 因式分解该整数if(num 2) {return Stream.of(num);}ListInteger nums new ArrayList();int i num;while (i 2) {for(int j 2; j i; j) {if(i % j 0) {nums.add(j);i / j;break;}}}return nums.stream();
}).forEach(System.out::println);注意map()和flatMap()这两个方法都能实现改变数据类型主要区别是map()方法修改类型后返回的是单个元素、flatMap()方法修改类型后返回的是一个stream流主要用于修改类型后返回的是一个集合的场景。 7. 获取数据peek()方法 在数据流处理过程中我们想查看一下当前数据的内容或记录数据信息到日志中可以通过peek()方法执行该方法只是对数据查看而不会改变数据的内容
// 打印数据
stream.peek(System.out::println).forEach(System.out::println);peek()方法与forEach()方法的区别是peek()输出数据后不影响流的继续操作而forEach()方法输出数据后流不能继续执行。peek()方法执行虽然不能修改元素但是可以修改元素内属性的值而对流的执行不产生影响。
Data
Builder
public class DemoVo {private int id;private String name;
}ListDemoVo list Arrays.asList(DemoVo.builder().build(), DemoVo.builder().build(), DemoVo.builder().build());
// 通过peek()方法设置对象的属性值
list.stream().peek(System.out::println).peek(c - c.setName(name)).forEach(System.out::println);三、终结方法
终结方法执行完后这个流不能继续执行常见的终结方法有下面这些
max()、min()、count()三个取值方法
// 最大值
Integer max stream.max(Comparator.comparingInt(o - o)).get();
System.out.println(max);// 最小值
Integer min stream.min(Comparator.comparingInt(o - o)).get();
System.out.println(min);// 计数
long count stream.count();
System.out.println(count);forEach() 遍历流中的数据
stream.forEach(System.out::println);toArray()方法将流转换为数组
Integer[] arr stream.toArray(new IntFunctionInteger[]() {Overridepublic Integer[] apply(int value) {return new Integer[value];}
});// lambda表达式
Integer[] arr stream.toArray(value - new Integer[value]);
System.out.println(Arrays.toString(arr));collect()将流收集到指定类型集合中
// 收集到list
ListInteger list stream.collect(Collectors.toList());// 收集到set
SetInteger set stream.collect(Collectors.toSet());// 收集到map两个函数分别用于键的生成规则和值的生成规则要注意键不能重复否则会抛出异常
MapInteger, String map stream.collect(Collectors.toMap(new FunctionInteger, Integer() {Overridepublic Integer apply(Integer i) {return i;}
}, new FunctionInteger, String() {Overridepublic String apply(Integer i) {return val- i;}
}));// lambda表达式
MapInteger, String map stream.collect(Collectors.toMap(i - i, i - val- i));