继上次学习过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中的线程表现的更多相关文章

  1. 查看JVM中的线程名

    实例说明 在Java虚拟机中(JVM):除了用户创建的线程,还有服务于用户线程的其他线程.它们根据不同的用途被分到不同的组中进行管理.本实例将演示JVM中线程的名字及其所在组的名称. 关键技术 线程组 ...

  2. Qt入门(9)——Qt中的线程支持

    Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法.警告:所有的GUI类(比如,QWidget和它的子类),操作系统核心 ...

  3. java笔记--关于多线程如何查看JVM中运行的线程

    查看JVM中的线程 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890280.html "谢谢-- ThreadGrou ...

  4. 从Java到JVM到OS线程睡眠

    Java 中有时需要将线程进入睡眠状态,这时一般我们就会通过 Thread.sleep 使线程进入睡眠状态,接下去就看看执行该语句在 JVM 中做了什么. 简单例子 以下是一个简单的例子,使主线程睡眠 ...

  5. 「每日五分钟,玩转JVM」:线程共享区

    前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计 ...

  6. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  7. 记一次用arthas排查jvm中CPU占用过高问题

    记一次使用arthas排查jvm中CPU占用过高问题.这工具屌爆了 碾压我目前使用的全部JVM工具. 安装 小试 curl -O https://arthas.aliyun.com/arthas-bo ...

  8. [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路

    Stream的概念定义   官方文档是永远的圣经~     表格内容来自https://docs.oracle.com/javase/8/docs/api/   Package java.util.s ...

  9. 99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?

    本文转载自公众号:石彬的架构笔记,阅读大约需要8分钟. 作者:李瑞杰 目前就职于阿里巴巴,资深 JVM 研究人员 在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我 ...

随机推荐

  1. luogu P3386 【模板】二分图匹配

    二次联通门 : luogu P3386 [模板]二分图匹配 /* luogu P3386 [模板]二分图匹配 最大流 设置源点,汇点,连到每条边上 跑一边最大流即可 */ #include <i ...

  2. Excel表格内容导出到页面

    引入org.apache.poi.ss.usermodel   public void addExcelBooks() throws Exception { HttpServletRequest re ...

  3. [bzoj 5332][SDOI2018]旧试题

    传送门 Description \[ \sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^Cd(ijk) (\mathrm{mod\:} 10^9+7) \] 其中 \(d(ijk) ...

  4. 配置centos7阿里镜像源和epel源

    [root@runstone yum.repos.d]# pwd /etc/yum.repos.d [root@runstone yum.repos.d]# cat aliBase.repo #镜像源 ...

  5. NPM私有包部署到私有仓库

    NPM私有包部署到私有仓库1.项目部署到NPM2.私有仓库的搭建1,项目部署到NPM注册NPM账号注册地址:https://www.npmjs.com/ 注册完成后进入邮箱验证 账号登录 npm lo ...

  6. 爬虫前提——正则表达式语法以及在Python中的使用

    正则表达式是用来处理字符串的强大工具,他并不是某种编程云. 正则表达式拥有独立的承受力引擎,不管什么编程语言,正则表达式的语法都是一样的. 正则表达式的匹配过程 1.一次拿出表达式和文本中的字符比较. ...

  7. pc电源cpu插座和显卡插座

    cpu插座是8口的,一般4+4 显卡插座是6口的,也有8口的用6+2 6+2的中2有一个小边,组合成8口也不能插入cpu插座.

  8. jQuery 设置select,radio的值,无法自动触发绑定的change事件

    一.问题 今天在对select和radio做change事件绑定后,手动设置其value值,但是不能触发change事件 二.解决 使用trigger方法手动触发

  9. php手记之05-tp5模型操作数据库

    # 实例化模型 // $user = new User; // $user1 = new User(); // $user2 = model('user'); // 添加一条数据 # 方法1 // $ ...

  10. secureCRT操作redis-cli时, 不断追加ip:port

    Session Options-->Terminal-->Emulation-->Terminal为Linux