目录
前言
今天我们主要对于stream操作List集合作一个小总结,在之前看到有很多人都使用stream就很好奇,主要看一下stream中提供的方法对于集合的操作.
一.stream的使用场景特点
Stream属于java.util包下的一个工具类,stream是java8提供的一个新特性,java8提供Lambda表达式,还有我们的stream,在stream中也有lambda表达式的应用,stream和lambda只是其中的之二还有很多新特性就不一一列举了
特点:
1.java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
2.Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算 和 表达的高阶抽象。
3.Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
4.这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处 理, 比如筛选, 排序,聚合等。
5.元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果
二.初步体验一下stream
1.Stream是元素的集合,这点让Stream看起来有些类似Iterator(迭代器);
2.可以支持顺序和并行的对原Stream进行汇聚的操作
3.代码演示:
public class Demo1 {
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);
list.add(null);
list.add(3);
list.add(null);
long l=list.stream().filter(nums->nums !=null).count();
System.out.println(l);//我们的预期是:2
}
}
看输出结果和我们的预期姐果是否一样(最后结果与预期相同)
解析:各段代码的意义
流程:获取数据源->进行一次或多次逻辑转换操作->进行归约操作形成新的流(最后可以将流转换成集合)这使得我们可以随意操作流并得到我们想要的数据.
这是一个stream的一个小例子.通过一小段代码可以感受到stream对于集合的操作有这很强的效果
三.简单看一下Stream的常用API
首先定义两个集合用于以下的实例操作.
实例一:
public class Demo2 {
public static void main(String[] args) {
// 定义一个集合
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三请客");
list.add("李四不去");
list.add("王五去");
list.add("李四后悔了");
}
}
实例二:
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
list1.add(6);
list1.add(7);
3.1 forEach()遍历集合中的对象
list.stream().forEach(lists-> System.out.println(lists));
输出结果
3.2filter对流对象进行过滤
代码意义为名字长度不为二的有几个
list.stream().filter((String)->String.length()!=2).count();//预计是4
输出结果:
3.3map()方法:
注释:map 方法用于映射每个元素到对应的结果
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
System.out.println(squaresList);
输出结果:
3.4count():计数
注释:count是对流数据统计的方法,但是count之后返回的是long类型,所以无法再进行流操作(在上图中3.2代码演示中已经演示过这里就不作演示了)
3.5 limit():选取流数据的前多少条数据
//获取两条数据
list.stream().limit(2).forEach(System.out::println);//预计结果为:张三李四
输出结果:
3.6 skip():跳转
注释:跳过流数据的前多少条数据,该方法与limit()方法刚好相反
//跳过前6条数据
list1.stream().skip(6).forEach(System.out::println);//预计输出结果为:7
输出结果:
3.7sorted ()排序
用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
输出结果:
3.8 并行(parallel)程序(之前在项目中用过)
List<String> strings = Arrays.asList("111", "", "bc12", "efg", "abcd","", "33l","");
// 获取空字符串的数量
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();//预计是输出: 3
输出结果:
3.9 concat():合并
注释:Stream的静态方法concat()实现对两个流数据进行合并
/**
* <pre>
* stream小练习
* </pre>
* @author qsg
* @since 2022/4/9
*/
public class Demo2 {
public static void main(String[] args) {
// 定义一个集合
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三请客");
list.add("李四不去");
list.add("王五去");
list.add("李四后悔了");
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
list1.add(6);
list1.add(7);
//concat()实现对两个流数据进行合并
Stream.concat(list.stream(),list1.stream()).forEach(System.out::println);
}
}
输出结果:
Stream api 还有distinct(),find系列,faltMap系列 等,Stream还有许多的api这里就不一一列举了,主要体验一下Stream对与集合的操作强大之处.
四.总结:
4.1stream的实际开发好处
1.它是java对集合操作的优化,相较于迭代器,使用Stream的速度非常快,并且它支持并行方式处理集合中的数据,默认情况能充分利用cpu的资源。同时支持函数式编程,代码非常简洁。
2.Stream是一种用来计算数据的流,它本身并没有存储数据。你可以认为它是对数据源的一个映射或者视图这让我们使用起来方便简洁.
3.它的工作流程是:获取数据源->进行一次或多次逻辑转换操作->进行归约操作形成新的流(最后可以将流转换成集合)这使得我们可以随意操作流并得到我们想要的数据.
4.stream流操作简化了我们平时对集合数据的操作,java8对此进行了优化,提高我们的开发效率
4.2stream应用中的不足
1.代码难以调试,因为不像for循环那样可以每一行打断点调试了
2.在数据量不是很大的情况下,stream流是没有优势的,也就是说数据量小,且同意业务内多处使用stream处理数据,这时执行耗时比for循环更多,只有业务量达到百万级别才体现出优势。
3.不要重复消费对象、不要修改数据源