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 语句之外,我 ...
随机推荐
- 爬虫(三):Requests库的基本使用
一:什么是Requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用,你会发现 ...
- c++ ros 计算两点距离
#include <iostream> /* puts, printf */ #include <time.h> /* time_t, struct tm, time, loc ...
- OpenJudge 1.5.27:级数求和
描述 已知:Sn= 1+1/2+1/3+…+1/n.显然对于任意一个整数K,当n足够大的时候,Sn大于K. 现给出一个整数K(1<=k<=15),要求计算出一个最小的n:使得Sn>K ...
- 同一个类里@Cacheable缓存不起作用
问题原因: 注解@Cacheable是使用AOP代理实现的 ,通过创建内部类来代理缓存方法,类内部的方法调用类内部的缓存方法不会走代理,所以就不能正常创建缓存,所以每次都需要去调用数据库. 解决方法: ...
- AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u012881904/article/de ...
- 常见ETL工具一览
这些年,几乎都与ETL打交道,接触过多种ETL工具.现将这些工具做个整理,与大家分享. 一 ETL工具[国外] 1. datastage点评:最专业的ETL工具,价格不菲,使用难度一般 下载地址:ft ...
- Windows平台下Java,tomcat安装与环境配置
问题描述:在Windows下面做Java web相关的项目的时候,Java和tomcat是基础,这里记载一下Java环境的配置以及tomcat的安装和配置. 使用工具:Windows.jdk安装包.t ...
- DOM 事件有哪些阶段?谈谈对事件代理的理解
分为三大阶段:捕获阶段--目标阶段--冒泡阶段 事件代理简单说就是:事件不直接绑定到某元素上,而是绑定到该元素的父元素上,进行触发事件操作时(例如'click'),再通过条件判断,执行事件触发后的语句 ...
- linux设置su和sudo为不需要密码
一 设置sudo为不需要密码 有时候我们只需要执行一条root权限的命令也要su到root,是不是有些不方便?这时可以用sudo代替.默认新建的用户不在sudo组,需要编辑/etc/sudoers ...
- Matlab注释的几个方法
Matlab最简单的注释当然是 %x= %这是注释,无法运行 x= %结果为2 然而%只能注释一行,如何注释更加快捷简便地注释多行呢? %{ .这就是传说中的多行注释 .成功! %} 经常需要调试程序 ...