Stream入门及Stream在JVM中的线程表现
继上次学习过Java8中的非常重要的Lambda表达式之后,接下来就要学习另一个也比较重要的知识啦,也就如标题所示:Stream,而它的学习是完全依赖于之前学习的Lambda表达式。
小实验引入:
这里继续参照java8 in action,关于Stream也是有专门章节去介绍的:

下面就正式开启Stream的学习之旅,这里先做一个实验,用实验来引起Stream,而这实验来源于书中,关于菜方面滴:

所以跟着书本上的来,先建一个菜的实体:
/**
* 菜实体
*/
public class Dish { /* 菜名 */
private final String name;
/* 是否是素食 */
private final boolean vegetarian;
/* 卡路里 */
private final int calories;
/* 菜的类型 */
private final Type type; public Dish(String name, boolean vegetarian, int calories, Type type) {
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
} public String getName() {
return name;
} public boolean isVegetarian() {
return vegetarian;
} public int getCalories() {
return calories;
} public Type getType() {
return type;
} public enum Type {MEAT, FISH, OTHER} @Override
public String toString() {
return "Dish{" +
"name='" + name + '\'' +
", vegetarian=" + vegetarian +
", calories=" + calories +
", type=" + type +
'}';
}
}
然后想从一个菜集合中拿到低于400卡路里的所有菜,并且以卡路里进行排序,而且最终只需要拿到满足条件的菜名,而非菜的实体,所以首先先构建一个集合:
public class SimpleStream {
public static void main(String[] args) {
List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER), new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER), new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH));
}
}
首先用传统的方式来获取上面条件的菜,比较简单:
public class SimpleStream {
public static void main(String[] args) {
List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER), new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER), new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH));
List<String> disNamesByCollections = getDishNamesByCollections(menu);
System.out.println(disNamesByCollections);
}
private static List<String> getDishNamesByCollections(List<Dish> menu) {
List<Dish> lowCalories = new ArrayList<>();
for (Dish dish : menu) {
if (dish.getCalories() < 400)
lowCalories.add(dish);
}
Collections.sort(lowCalories, (d1, d2) -> Integer.compare(d1.getCalories(), d2.getCalories()));
List<String> dishNameList = new ArrayList<>();
for (Dish lowCalory : lowCalories) {
dishNameList.add(lowCalory.getName());
}
return dishNameList;
}
}
编译运行:

那如果采用stream方式实现同样的功能,那代码是长啥样呢?首先在集合中会有一个方法将它转成Stream对象,如下:

所以可以这么写代码:

首先去做条件过滤:卡路里<400,其Stream中就有现成过滤的方法:


所以加入过滤条件:

接着对颜色进行排序,那如何整呢?Stream依然有专门排序的方法,继续可以链下去调用:

而据之前学习的方法推导,所以上面排序的代码改用方法推荐如下:

接着从结果集中只取出名字,接着可以调用Stream的这个方法:

最后则返回List,如下:

是不是写法有些怪异,查看一下它的源码:


接着来调用一下用stream实现的方式,但输出是否也能正确:


直观的感受下这两者的实现代码:

什么是stream?
这时再来看下书中对它的介绍:

只是这个细节被隐藏了,关于并行处理,可以看一下Stream的源码:


那如何验证这个stream是并发处理的呢?这里通过jconsole来查看一下线程运行情况。
Stream在JVM中的线程表现
首先先查看一下普通方式在JVM线程中的表现:

运行,然后用jconsole连接上:



接着换成stream方式,将普通方式注掉:

这时运行:

然后用jconsole来连接查看一下当前jvm的线程情况:


呃,貌似跟之前使用普通的方式在JVM中线程一样,那何以知道使用stream方式是以并发的方式呢?这里要想让stream并行处理需要改造一下代码如下:

这时运行再用jconsole来查看就可以感知到啦:

Stream入门及Stream在JVM中的线程表现的更多相关文章
- 查看JVM中的线程名
实例说明 在Java虚拟机中(JVM):除了用户创建的线程,还有服务于用户线程的其他线程.它们根据不同的用途被分到不同的组中进行管理.本实例将演示JVM中线程的名字及其所在组的名称. 关键技术 线程组 ...
- Qt入门(9)——Qt中的线程支持
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...
- java笔记--关于多线程如何查看JVM中运行的线程
查看JVM中的线程 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890280.html "谢谢-- ThreadGrou ...
- 从Java到JVM到OS线程睡眠
Java 中有时需要将线程进入睡眠状态,这时一般我们就会通过 Thread.sleep 使线程进入睡眠状态,接下去就看看执行该语句在 JVM 中做了什么. 简单例子 以下是一个简单的例子,使主线程睡眠 ...
- 「每日五分钟,玩转JVM」:线程共享区
前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 记一次用arthas排查jvm中CPU占用过高问题
记一次使用arthas排查jvm中CPU占用过高问题.这工具屌爆了 碾压我目前使用的全部JVM工具. 安装 小试 curl -O https://arthas.aliyun.com/arthas-bo ...
- [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路
Stream的概念定义 官方文档是永远的圣经~ 表格内容来自https://docs.oracle.com/javase/8/docs/api/ Package java.util.s ...
- 99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?
本文转载自公众号:石彬的架构笔记,阅读大约需要8分钟. 作者:李瑞杰 目前就职于阿里巴巴,资深 JVM 研究人员 在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我 ...
随机推荐
- CSPS2019游(tuifei)记
%%%脸哥没脸%%% Day0,日常考前紧张,做不下题去.听各大主任送祝福(从里红(wa)到外) 然后就出发了,大巴上和云力一起坐,吃了好多东西.中午因不满火车站的不合理收费,选择了面包+火腿 下午在 ...
- P3956 棋盘——普及题,儿童搜索
P3956 棋盘 这道搜索弄得我很难受. 第一,一定要看清楚题在写.第二,弄清楚判断条件: 首先图的大小是m*m不是n*m; 然后就是当前有颜色的点是不用变颜色的: #include<cstdi ...
- pyCharm专业版破解方案【附:四种破解】
前言: 一般适合我们的工具才是好的工具,通过调研对比发现pycharm还不错,其它工具就不一一列举了 pyCharm社区版可以永久免费,但是它不支持HTML, JS, and SQL等,为了方便以后使 ...
- Python豆瓣书籍信息爬虫
练习下BeautifulSoup,requests库,用python3.3 写了一个简易的豆瓣小爬虫,将爬取的信息在控制台输出并且写入文件中. 上源码: # coding = utf-8 '''my ...
- WPF中打开网页的两种方法
1.浏览器打开 Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = "http://www. ...
- 上传本地文件到github仓库
第一步:新建仓库 给仓库一个名字,备注 得到仓库地址: https://github.com/Lucasli2018/java-1-mybatis.git 第二步:进入要上传的文件夹,初始化上传文件夹 ...
- 学习OpenCV双目测距原理及常见问题解答
学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图 ...
- Solr 集成ikanalyzer
Solr 不能对中文进行分词,ikanalyzer可以. ikanalyzer下载链接 1.下载 jar形式 2.放到D:\soft\solr-8.1.0\server\solr-webapp\web ...
- [GitHub]纪华裕的GitHub收藏
由于GitHub的star没有分类功能在此写下我的收藏. JS nodenodejs的仓库 puppeteer一个用户测试的无头浏览器 moment日期操作库,包括格式化等
- arcgis python 调用工具两种两种方法
arcpy.Select_analysis("p","kk") arcpy.analysis.Select("p","kk1&qu ...