初识Java8中的Stream

论坛 期权论坛     
niminba   2021-5-22 15:23   84   0
<p>lambda表达式是stream的基础,初学者建议先学习lambda表达式,<a href="https://www.jb51.net/article/121129.htm">https://www.jb51.net/article/121129.htm</a></p>
<p><span style="color: #ff0000"><strong>1.初识stream</strong></span></p>
<p>先来一个总纲:</p>
<p style="text-align: center"><img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-04be69c372b387b6b625712a2ca5fa64.png" style="font-size: medium; font-family: Simsun; white-space: normal; word-spacing: 0px; text-transform: none; font-weight: normal; color: rgb(0,0,0); font-style: normal; orphans: 2; widows: 2; letter-spacing: normal; text-indent: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px"></p>
<p>东西就是这么多啦,stream是java8中加入的一个非常实用的功能,最初看时以为是io中的流(其实一点关系都没有),让我们先来看一个小例子感受一下:</p>
<div class="blockcode">
<pre class="brush:java;">
@Before
public void init() {
random = new Random();
stuList = new ArrayList&lt;Student&gt;() {
{
for (int i = 0; i &lt; 100; i++) {
add(new Student("student" + i, random.nextInt(50) + 50));
}
}
};
}
public class Student {
private String name;
private Integer score;
//-----getters and setters-----
}
//1列出班上超过85分的学生姓名,并按照分数降序输出用户名字
@Test
public void test1() {
List&lt;String&gt; studentList = stuList.stream()
.filter(x-&gt;x.getScore()&gt;85)
.sorted(Comparator.comparing(Student::getScore).reversed())
.map(Student::getName)
.collect(Collectors.toList());
System.out.println(studentList);
}</pre>
</div>
<p>列出班上分数超过85分的学生姓名,并按照分数降序输出用户名字,在java8之前我们需要三个步骤:</p>
<p>1)新建一个List&lt;Student&gt; newList,在for循环中遍历stuList,将分数超过85分的学生装入新的集合中</p>
<p>2)对于新的集合newList进行排序操作</p>
<p>3)遍历打印newList</p>
<p>这三个步骤在java8中只需要两条语句,如果紧紧需要打印,不需要保存新生产list的话实际上只需要一条,是不是非常方便。</p>
<p><span style="color: #ff0000"><strong>2.stream的特性</strong></span></p>
<p>我们首先列出stream的如下三点特性,在之后我们会对照着详细说明</p>
<p>1.stream不存储数据</p>
<p>2.stream不改变源数据</p>
<p>3.stream的延迟执行特性</p>
<p>通常我们在数组或集合的基础上创建stream,stream不会专门存储数据,对stream的操作也不会影响到创建它的数组和集合,对于stream的聚合、消费或收集操作只能进行一次,再次操作会报错,如下代码:</p>
<div class="blockcode">
<pre class="brush:java;">
@Test
public void test1(){
Stream&lt;String&gt; stream = Stream.generate(()-&gt;"user").limit(20);
stream.forEach(System.out::println);
stream.forEach(System.out::println);
}</pre>
</div>
<p style="text-align: center"><img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-d6216df026da28f6acb9674afb592708.png" style="font-size: medium; font-family: Simsun; white-space: normal; word-spacing: 0px; text-transform: none; font-weight: normal; color: rgb(0,0,0); font-style: normal; orphans: 2; widows: 2; letter-spacing: normal; text-indent: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px"></p>
<p>程序在正常完成一次打印工作后报错。</p>
<p>stream的操作是延迟执行的,在列出班上超过85分的学生姓名例子中,在collect方法执行之前,filter、sorted、map方法还未执行,只有当collect方法执行时才会触发之前转换操作</p>
<p>看如下代码:</p>
<div class="blockcode">
<pre class="brush:java;">
public boolean filter(Student s) {
System.out.println("begin compare");
return s.getScore() &gt; 85;
}

@Test
public void test() {
Stream&lt;Student&gt; stream = Stream.of(stuArr).filter(this::filter);
System.out.println("split-------------------------------------");
List&lt;Student&gt; studentList = stream.collect(toList());
}</pre>
</div>
<p>我们将filter中的逻辑抽象成方法,在方法中加入打印逻辑,如果stream的转换操作是延迟执行的,那么split会先打印,否则后打印,代码运行结果为</p>
<p style="text-align: center"><img alt="" src="https://beijingoptbbs.oss-cn-hangzhou.aliyuncs.com/jb/2426819-5815304185c6fb60d28cf3b4e960e929.png" style="font-size: medium; font-family: Simsun; white-space: normal; word-spacing: 0px; text-transform: none; font-weight: normal; color: rgb(0,0,0); font-style: normal; orphans: 2; widows: 2; letter-spacing: normal; text-indent: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px"><img alt="" style="font-size: medium; font-family: Simsun; white-space: normal; word-spacing: 0px; text-transform: none; font-weight: normal; color: rgb(0,0,0); font-style: normal; orphans: 2; widows: 2; letter-spacing: normal; text-indent: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px"></p>
<p>可见stream的操作是延迟执行的。</p>
<p>TIP:</p>
<p>当我们操作一个流的时候,并不会修改流底层的集合(即使集合是线程安全的),如果想要修改原有的集合,就无法定义流操作的输出
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP