java8学习之内部迭代与外部迭代本质剖析及流本源分析
关于Stream在Java8中是占非常主要的地位的,所以这次对它进行进一步探讨【这次基本上都是偏理论的东东,但是理解它很重要~】,其实流跟咱们数据库学习当中的sql语句的特点是非常非常之像的,为什么这么说,下面以这个sql语句举例说明:
“select name from student where age > 20 and address = 'beijing' order by age desc;”
该简单的sql所要表达的意思是:从student这张表中查询出年龄>20并且地址=北京的记录,并且对年龄进行降序排序,排序之后将其名字查找出来。对于sql其实是一个描述性的语言,只描述其行为,而具体如何让db完成这个行为是没有暴露出来的,对于该sql所做的工作如果换成咱们的stream来实现那会是个什么样子呢,下面写一下伪代码:
首先从源数据中获得stream:
students.stream();
接着进行条件过滤:age > 20 and address = 'beijing',如下:
students.stream().filter(student -> student.getAge() > 20).filter(student -> student.getAddress().equals("beijing"));
然后对年纪进行排序,这里写伪代码:
students.stream().filter(student -> student.getAge() > 20).filter(student -> student.getAddress().equals("beijing")).sorted(...);
最后将其名字打印出来,如下:
students.stream().filter(student -> student.getAge() > 20).filter(student -> student.getAddress().equals("beijing")).sorted(...).forEach(student -> System.out.println(student.getName()));
是不是从表现形式上跟sql语句差不多,Stream也是属于一种描述性的语句, 整个语句并没有告诉底层Stream要如何去做,等于只要发一些指令给底层就可以了,具体底层怎么做完全不用关心。
其实对于这种Stream()的这种方式是一种内部迭待,而如果换成传统的方式既为外部迭待方式,如下:
List<Student> list = new ArrayList<>(); //首先对数据进行条件过滤
for(int i=0; i < students.size();i++){
Student student = students.get(i);
if(student.getAge() > 20 && student.getAddress().equals("beijing")){
list.add(student);
}
} //接着对其按年龄排序
Collections.sort(list. Comparator()...); //将名字打印出来
for(Student student : list){
System.out.println(student.getName());
}
是不是发现跟使用Stream的方式完全没法相比,相差太多了,而且本质上也有区别,之所以上面传统的方式为外部迭待,很显然用到了一个中间的临时变量,另外将业务条件跟具体遍历代码都混在一起了,语义上理解也没这么容易,假如说对于一个不懂代码的人来看这两种实现方式,肯定是看具有描述性语句的stream的方式更加容易理解。
接下来用图的方式来阐述一下内部迭待与外部迭待的本质区别:
外部迭待:
针对一个集合:
以咱们这个例子为例,会使用for循环对其进行迭待,所以会单独在集合之外写入咱们自己的处理逻辑,如下:
其中集合与咱们自己编写的处理逻辑之间是有清晰的划分的:
内部迭待:
那对于stream的内部迭待方式表现又如何呢?
首先操作的对象就不是集合啦,而是集合的流,如下:
而接下来内的体现就来了,咱们自己写的代码和流会融合在一起了,而非自己写的这块代码相对于流是独立的:
合并到一起有什么好处呢?这样流就可以拿到咱们自己所提供的代码进行相应的优化,当遇到咱们调用的终止操作则将咱们提供的所有中间操作与流之前所提供好的基础功能进行统一的处理。
其实内部迭待有点像是做填充题一样,对于一篇写好的英文文章,空缺了几个填充选项【将某个单词或某个语句被扣出来了】,而咱们写的代码其实就是填补这些空缺的地方,而不是完全由自己发挥想象来写这篇英文文章;而传统的外部迭代方式则是给一个命题里面所有的内容都得由自己来编写。
另外内部迭待与外部迭待还有另外一个最大的区别,那就是内部迭待支持并行处理,而所有的并行处理其stream都已经代替咱们来处理了,也就是从调用者的角度来想就不用关心处理并行的问题,而传统的外部迭待一般都是串行的,如果也想要并行处理那这个并行的东东完全得自己来处理。
对于集合和流最后再来用一句话来概括:集合关注的是数据与数据存储本身;流关注的则是对数据的计算。而流与迭待器类似的一点是:流是无法重复使用或消费的。
另外对于流再来说明一下:对于流来说,中间操作都会返回一个Stream对象,而终止操作则不会返回Stream类型,它可能不返回值,也可能返回其它类型的单个值。所以说区分中间操作与终止操作的条件就是看返回的类型,如果是Stream对象一定是中间操作。
java8学习之内部迭代与外部迭代本质剖析及流本源分析的更多相关文章
- java8学习之收集器枚举特性深度解析与并行流原理
首先先来找出上一次[http://www.cnblogs.com/webor2006/p/8353314.html]在最后举的那个并行流报错的问题,如下: 在来查找出上面异常的原因之前,当然得要一点点 ...
- JAVA8学习——从使用角度深入Stream流(学习过程)
Stream 流 初识Stream流 简单认识一下Stream:Stream类中的官方介绍: /** * A sequence of elements supporting sequential an ...
- 初探Lambda表达式/Java多核编程【0】从外部迭代到内部迭代
开篇 放假前从学校图书馆中借来一本书,Oracle官方的<精通Lambda表达式:Java多核编程>. 假期已过大半才想起来还没翻上几页,在此先推荐给大家. 此书内容及其简洁干练,如果你对 ...
- NumPy 超详细教程(3):ndarray 的内部机理及高级迭代
系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 ndarray 对象的内部机理 ...
- PythonI/O进阶学习笔记_8.python的可迭代对象和迭代器、迭代设计模式
content: 1.什么是迭代协议 2. 什么是迭代器(Iterator)和可迭代对象(Iterable) 3. 使用迭代器和可迭代对象 4. 创建迭代器和可迭代对象 5. 迭代器设计模式 一 ...
- hive学习笔记之三:内部表和外部表
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 大数据学习day26----hive01----1hive的简介 2 hive的安装(hive的两种连接方式,后台启动,标准输出,错误输出)3. 数据库的基本操作 4. 建表(内部表和外部表的创建以及应用场景,数据导入,学生、分数sql练习)5.分区表 6加载数据的方式
1. hive的简介(具体见文档) Hive是分析处理结构化数据的工具 本质:将hive sql转化成MapReduce程序或者spark程序 Hive处理的数据一般存储在HDFS上,其分析数据底 ...
- java8学习之深入函数式接口与方法引用
函数式接口: 函数式接口[FunctionalInterface]是整个Lambda表达式的一个根源,换句话来说java8中的Lambda表达式要想彻底掌握,前提是要彻底理解好函数式接口,所以这次继续 ...
- JAVA8学习——深入浅出Lambda表达式(学习过程)
JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...
随机推荐
- idea 错误: 找不到或无法加载主类 xxx.xxx.xxxxx
idea 错误: 找不到或无法加载主类 xxx.xxx.xxxxx JDK环境,maven项目还是ee还是web项目,是否都正常. 如果是用idea打开的话,在源码目录上点击右键,然后找到Mark d ...
- 从 ssh private key 中重新生成 public key
Use the -y option to ssh-keygen: ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub From the 'man ...
- style属性
style加样式是加在行间,取样式也是在行间取: 我们来看下面这段代码: <!DOCTYPE HTML> <html> <head> <meta charse ...
- 083. Remove Duplicates from Sorted List
题目链接:https://leetcode.com/problems/rotate-list/description/ Given a sorted linked list, delete all d ...
- Django学习笔记(一)Django基础
新建项目 django-admin startproject my_site #会在当前目录新建my_site目录,可自行修改目录名 django-admin startproject my_site ...
- 注入之Mysql-Getshell思路
- python 爬虫小案例
爬取百度贴吧帖子信息 #!/usr/bin/env python # -*- coding: utf-8 -*- # author: imcati import requests,re,time cl ...
- LeetCode-求最长回文子序列
题目:给定一个字符串,求它的最长回文子串 /*求最长回文子串,以当前字符为中心,向两边同时拓展*/ string longestPalindrome(string s) { int len = s.l ...
- OI模板のpoke流[大型考试复习必备/kl]
数论 快速乘: ll qmul(ll x,ll y,ll mod) { ll ans=0; while(y) { if(y&1) (ans+=x)%=mod; y>>=1; (x+ ...
- 爬取糗事百科热门段子的数据并保存到本地,xpath的使用
和之前的爬虫类博客的爬取思路基本一致: 构造url_list,因为糗事百科的热门栏目默认是13页,所以这个就简单了 遍历发送请求获取响应 提取数据,这里用的是xpath提取,用的是Python的第三方 ...