继上次学习过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 P3567 [POI2014]KUR-Couriers

    二次联通门 : luogu P3567 [POI2014]KUR-Couriers MMP 指针 RE + MLE + WA..... 不得已...向黑恶的数组实力低头 /* 指针 */ #inclu ...

  2. 【转载】Hadoop集群各部分常用端口号

    hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问.而随着hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如 ...

  3. php语言查询Mysql数据库内容

    通过php语言实现对Mysql数据库的基本操作 1.php页面在进行浏览时需要有php语言执行的环境,本人用的是WampServer软件,只要将项目复制到wampserver_php\wamp\www ...

  4. [微信小程序]实现一个自定义遮罩层

    正文: 先上效果图: 点击按钮Show显示遮罩层,再次点击屏幕任何地方隐藏遮罩层; <button bindtap="showview">Show</button ...

  5. 二维背包---P1855 榨取kkksc03

    P1855 榨取kkksc03 题解 二维背包板子题 f[ i ][ j ] 前 n 个物品,花费金钱不超过 i ,花费时间不超过 j 的最大价值 如果每个物品只能选一次,那么就相当于在01背包上多加 ...

  6. 记一次被DDoS敲诈的历程 糖果LUA FreeBuf 今天 0x01 背景

    记一次被DDoS敲诈的历程 糖果LUA FreeBuf 今天 0x01 背景

  7. Somatic hypermutation (or SHM) is a cellular mechanism by which the immune system adapts to the new foreign elements that confront it (e.g. microbes), as seen during class switching. Somatic hypermut

    Somatic hypermutation (or SHM) is a cellular mechanism by which the immune system adapts to the new ...

  8. 在 Java 应用程序中加一些 Groovy 进来

    如果您一直在阅读这个系列,那么您应该已经看到有各种各样使用 Groovy 的有趣方式,Groovy 的主要优势之一就是它的生产力.Groovy 代码通常要比 Java 代码更容易编写,而且编写起来也更 ...

  9. Android 定义和使用样式

    如图,在stryle.xml中定义样式 然后可以在布局文件中使用样式

  10. JavaScript Functional Programming:声明式与命令式

    函数式编程属于声明式编程(declarative programming)的范畴,经常跟声明式编程一块儿讨论的是命令式编程(imperative programming),因为它们是两种不太一样的风格 ...