
- 外文名
- Stream
- 基本解释
- 泛指流媒体技术
- 词 性
- 动词,名词
- 中文名
- 流媒体技术
-
Stream
2016-12-30 14:39:30Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 ...为什么需要Stream
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物。
@FunctionalInterface
被这个注解标记的inteface可以用lambda表达式替代参数。
Function<String, String> getAge = (s) -> s; Consumer<String> getAge2 = (s) -> {}; Supplier<String> heh = () -> "a";
Function和BiFunction对应1个入参和2个入参的
lambda表达式也是这么对应的1个还是2个参数使用::
java8可以用::产生lambda,不如:
System.out::println
String::concat::有上下文这个概念,我理解的就是调用这个方法需不需要一个对象去调用。
1.对于System.out::println,不需要上下文(可以直接调用,不需要对象去调用这个方法,因为System.out是static的,System.out.printn(a)),且println需要一个参数,那么System.out::println生成的lambda就是1个入参的,即() -> {}.
2.对于String::concat,需要上下文,且concat方法需要一个参数,那么String::concat生成的lambda机会是2个入参的,即(a, b) -> {},需要的上下文即第一个参数的类型必须为::前面的类型或者子类。如果因为方法能给提供的参数类型和上下文需要的类型不一致也不对,会报Non-static method cannot be referenced from a static context。example
List<String> list = Stream.of("1111", "222", "333", "4") .filter(e -> e.length() > 3) .peek(System.out::println) .map(ss -> ss.toUpperCase()) .peek(e -> System.out.println("Mapped value: " + e)) .collect(Collectors.toList());
Set<String> widgets = new HashSet<>(); widgets.add("1"); widgets.add("2"); widgets.add("3"); widgets.add("4"); String s = widgets.stream().collect(Collectors.joining(",", "(", ")"));
Stream<List<Integer>> inputStream = Stream.of( Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6) ); Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
参考
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
-
Stream和parallelStream
2019-04-22 15:16:54Stream 和 parallelStream 一.什么是Stream? Stream 是在 Java8 新增的特性,普遍称其为流;它不是数据结构也不存放任何数据,其主要用于集合的逻辑处理。 二.和Iterator的区别 Iterator 做为迭代器,其按照一定的...Stream 和 parallelStream
一.什么是Stream?
Stream 是在 Java8 新增的特性,普遍称其为流;它不是数据结构也不存放任何数据,其主要用于集合的逻辑处理。
二.和Iterator的区别
Iterator 做为迭代器,其按照一定的顺序迭代遍历集合中的每一个元素,并且对每个元素进行指定的操作。而 Stream 在此基础上还可以将这种操作并行化,利用多核处理器的优势快速处理集合(集合的数据会分成多个段,由多个线程处理)。
Stream 的数据源可以有无限多个。
三.Stream的使用
在使用Stream之前,建义先理解接口化编程,Stream将完全依赖于接口化编程方式。接下来我们以“打印集合中的每一个元素”为例,了解一下 Stream 的使用。
例3.1
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.stream().forEach(num->System.out.println(num)); 输出:1 2 3 4 5 6 7 8 9
由以上的列子可以看出,Stream 的遍历方式和结果与 Iterator 没什么差别,这是因为Stream的默认遍历是和迭代器相同的,保证以往使用迭代器的地方可以方便的改写为 Stream。
Stream 的强大之处在于其通过简单的链式编程,使得它可以方便地对遍历处理后的数据进行再处理。我们以“对集合中的数字加1,并转换成字符串”为例进行演示。
例3.2
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);` `List<String> strs = numbers.stream()` `.map(num->Integer.toString(++num)).collect(Collectors.toList());
其中map()方法遍历处理每一个元素,并且返回一个新的Stream,随后collect方法将操作后的Stream解析为List。
Stream还提供了非常多的操作,如filter()过滤、skip()偏移等等,想要了解更多可以去翻阅JDK1.8手册或者相关资料。
四.并行流parallelStream
parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。简单理解就是多线程异步任务的一种实现。
我们用例3.1中的示例演示一下parallelStream的使用。
例4.1
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.parallelStream().forEach(num->System.out.println(num)); 输出:3 4 2 6 7 9 8 1 5
我们发现,使用parallelStream后,结果并不按照集合原有顺序输出。为了进一步证明该操作是并行的,我们打印出线程信息。
例4.2
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.parallelStream() .forEach(num- >System.out.println(Thread.currentThread().getName()+">>"+num));
输出:
main>>6 ForkJoinPool.commonPool-worker-2>>8 main>>5 ForkJoinPool.commonPool-worker-2>>9 ForkJoinPool.commonPool-worker-1>>3 ForkJoinPool.commonPool-worker-3>>2 ForkJoinPool.commonPool-worker-1>>1 ForkJoinPool.commonPool-worker-2>>7 main>>4
通过例4.2可以确信parallelStream是利用多线程进行的,这可以很大程度简化我们使用并发操作。
我们可以通过虚拟机启动参数
-Djava.util.concurrent.ForkJoinPool.common.parallelism=N
来设置worker的数量。
五.并行流的陷阱
5.1.线程安全
由于并行流使用多线程,则一切线程安全问题都应该是需要考虑的问题,如:资源竞争、死锁、事务、可见性等等。
5.2.线程消费
在虚拟机启动时,我们指定了worker线程的数量,整个程序的生命周期都将使用这些工作线程;这必然存在任务生产和消费的问题,如果某个生产者生产了许多重量级的任务(耗时很长),那么其他任务毫无疑问将会没有工作线程可用;更可怕的事情是这些工作线程正在进行IO阻塞。
本应利用并行加速处理的业务,因为工作者不够反而会额外增加处理时间,使得系统性能在某一时刻大打折扣。而且这一类问题往往是很难排查的。我们并不知道一个重量级项目中的哪一个框架、哪一个模块在使用并行流。
接下来我们对这个问题进行演示:
例5.1
输出:
通过示例我们会发现,第一个并行流率先获得worker线程的使用权,第二个并行流变为串行;直到第14行,第一个并行流处理完毕,第二个并行流获取worker线程,开始并行处理。
小结:
串行流:适合存在线程安全问题、阻塞任务、重量级任务,以及需要使用同一事务的逻辑。
并行流:适合没有线程安全问题、较单纯的数据处理任务。
-
java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch
2018-06-23 15:46:33对于中间操作和终端操作的定义,请看《JAVA8 stream接口 中间操作和终端操作》,这篇主要讲述的是stream的count,anyMatch,allMatch,noneMatch操作,我们先看下函数的定义 long count(); boolean anyMatch...对于中间操作和终端操作的定义,请看《JAVA8 stream接口 中间操作和终端操作》,这篇主要讲述的是stream的count,anyMatch,allMatch,noneMatch操作,我们先看下函数的定义
long count(); boolean anyMatch(Predicate<? super T> predicate); boolean allMatch(Predicate<? super T> predicate); boolean noneMatch(Predicate<? super T> predicate);
count方法,跟List接口的size一样,返回的都是这个集合流的元素的长度,不同的是,流是集合的一个高级工厂,中间操作是工厂里的每一道工序,我们对这个流操作完成后,可以进行元素的数量的和;
剩下的三个方法,传入的都是Predicate的函数式接口,接口定义请看《JAVA8 Predicate接口》;
anyMatch表示,判断的条件里,任意一个元素成功,返回true
allMatch表示,判断条件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
下面,看几个例子
List<String> strs = Arrays.asList("a", "a", "a", "a", "b"); boolean aa = strs.stream().anyMatch(str -> str.equals("a")); boolean bb = strs.stream().allMatch(str -> str.equals("a")); boolean cc = strs.stream().noneMatch(str -> str.equals("a")); long count = strs.stream().filter(str -> str.equals("a")).count(); System.out.println(aa);// TRUE System.out.println(bb);// FALSE System.out.println(cc);// FALSE System.out.println(count);// 4
通过例子可以看到,变量aa的表达式,strs里的元素,任意有“a”,表示true
变量bb的表达式,strs里的元素,全部为“a”,表示true,否则false
变量cc的表达式,strs里的元素,全部不为“a”,表示true,否则false
--------------------分割线---------------------------------------
先看下如下代码
public static void main(String[] args) { List<String> list = new ArrayList<>(); boolean allMatch = list.stream().allMatch(e -> e.equals("a")); boolean anyMatch = list.stream().anyMatch(e -> e.equals("a")); boolean noneMatch = list.stream().noneMatch(e -> e.equals("a")); System.out.println(allMatch);// true System.out.println(anyMatch);// false System.out.println(noneMatch);// true }
最近,有小伙伴留言说,
boolean allMatch = list.stream().allMatch(e -> e.equals("a"));
当list的为空集合时候,这个返回默认为true;按照实际的业务,理解这个的话,应该为false;然后网上搜索了一下,比较尴尬的是,很多都是抄下我之前的文章,秉承着,严谨的原则,查看了源码,下面是整个分析的过程;
详细看《java8 stream接口终端操作allMatch 当list为空集合的一些思考》
1.lambda表达式
《java8 lambda表达式,方法的引用以及构造器的引用》
2.函数式接口
3.stream接口操作
《JAVA8 Stream接口,map操作,filter操作,flatMap操作》
《JAVA8 stream接口 distinct,sorted,peek,limit,skip》
《java8 stream接口 终端操作 forEachOrdered和forEach》
《java8 stream接口 终端操作 toArray操作》
《java8 stream接口 终端操作 min,max,findFirst,findAny操作》
《java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch》
《java8 stream接口 终端操作 collect操作》
4.其他部分
-
使用 Java8的 stream对list数据去重,使用filter()过滤列表,list转map
2018-09-12 14:00:50list去重,根据对象某个属性、某几个属性... List unique = list.stream().distinct().collect(Collectors.toList()); 去除List中重复的对象 // Person 对象 public class Person { private String id; ...list去重,根据对象某个属性、某几个属性去重
去除List中重复的String
List unique = list.stream().distinct().collect(Collectors.toList());
去除List中重复的对象
// Person 对象 public class Person { private String id; private String name; private String sex; <!--省略 get set--> }
// 根据name去重 List<Person> unique = persons.stream().collect( Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new) );
// 根据name,sex两个属性去重 List<Person> unique = persons.stream().collect( Collectors. collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getName() + ";" + o.getSex()))), ArrayList::new) );
filter()过滤列表
List<Person> filterList = persons.stream().filter(p -> p.getSex().equals(1)).collect(Collectors.toList());
List转Map
从一个Person对象的List集合,取出
id
和name
组成一个map集合Map<String, String> collect = list.stream().collect(Collectors.toMap(p -> p.getId(), p -> p.getName()));
从 List 中取出某个属性的组成 list 集合
//1.提取出list对象中的一个属性 List<String> stIdList1 = stuList.stream().map(Person::getId).collect(Collectors.toList()); //2.提取出list对象中的一个属性并去重 List<String> stIdList2 = stuList.stream().map(Person::getId).distinct().collect(Collectors.toList());
-
java8 stream接口 终端操作 min,max,findFirst,findAny操作
2018-06-23 15:15:36对于中间操作和终端操作的定义,请看《JAVA8 stream接口 中间操作和终端操作》,这篇主要讲述的是stream的min,max,findFirst,findAny操作,我们先看下函数的定义 Optional<T> min(Comparator<? super... -
三分钟弄清楚Java8 Stream 常用操作-
2020-06-23 20:05:43Stream是Java8中的一大亮点,支持顺序和并行聚合操作的一系列元素,为了执行计算,流operations被组合成流管道 。 流管线由源(其可以是阵列,集合,生成函数,I / O通道等)组成,零个或多个中间操作 (其将流转换... -
java.util.stream.Stream
2020-03-22 20:21:38Stream -
Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合
2020-11-09 13:52:52Java8 Stream横空出世,让我们从繁琐冗长的迭代中解脱出来,集合数据操作变得优雅简洁。 这些操作:集合的filter(筛选)、归约(reduce)、映射(map)、收集(collect)、统计(max、min、avg)等等,一行代码即可... -
Java8 stream 之groupingBy() 分组排序
2017-12-29 12:06:37List matchsList = new ArrayList();... MatchsListMap = matchsList.stream() .collect(Collectors.groupingBy(Matchs::getMatchDate)); 此时MatchsListMap的排序规则是根据MatchDate降序的(默认),也就是说ma -
Java 8 stream的详细用法
2019-01-08 23:12:43Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以... -
stringstream常见用法介绍
2018-09-10 23:20:54本文主要介绍 C++ 中 stringstream 类的常见用法。 1 概述 <sstream> 定义了三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作。本文以 stringstream 为主... -
Java8新特性Stream之list转map及问题解决
2018-10-11 14:57:44List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap 具体用法实例如下: //声明一个List集合 List&lt;Person&gt; list = new ArrayList(); list.add(new Person(&... -
Stream API
2020-03-29 19:04:13Java8新特性--操作集合Stream API -
java8新特性 lambda Stream map(函数式编程)
2016-08-20 15:04:42java8新特性 lambda Stream map(函数式编程) 牛刀小试:使用Java8新特性获取股票数据https://blog.csdn.net/u014646662/article/details/82936131 Java8实战.pdf 下载:... -
JAVA8 Stream接口,map操作,filter操作,flatMap操作
2018-06-10 17:22:18这篇,我们来看Stream的一些中间操作,关于中间操作的一些介绍,可以看《JAVA8 stream接口 中间操作和终端操作》 1,filter操作,我们先看方法的定义 Stream<T> filter(Predicate<? super T> ... -
JDK新特性——Stream代码简洁之道
2020-10-24 12:17:54Stream 是一组用来处理数组、集合的API,Stream API 提供了一种高效且易于使用的处理数据的方式。 Java 8 中之所以费这么大的功夫引入 函数式编程 ,原因有两个: 代码简洁函数式编程写出的代码简洁且意图明确,... -
强大的Stream
2020-08-31 12:39:06Stream不会改变原来的数据,会返回一个新的持有结果的Stream Stream的步骤 创建Stream 一系列中间操作 中止操作 中间操作 中止操作 查找与匹配 函数名 解释 allMatch 是否匹配所有元素 anyMatch 是否... -
Stream 求和
2017-07-30 17:17:28Stream 求和 -
Java Stream流之求和
2019-07-15 17:56:38BigDecimal bb =list.stream().map(Plan::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add); int、double、long: double max = list.stream().mapToDouble(User::getHeight).sum(); ... -
-
深入浅出Stream和parallelStream
2018-02-07 18:25:17深入浅出parallelStream 什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 ... -
stream和parallelstream的区别
2019-01-28 16:57:39先上代码 public static void main(String[] args){ List<Integer> i=Arrays.asList(1,2,3,4,5,...stream.forEach打印结果如下"); i.stream().forEach(System.out :: println);//固定结... -
collection.stream()以及collect()方法
2018-08-06 20:57:00stream()方法和collect()方法都是java8的新特性 工作的时候看到同事写的代码有点不懂,故搜索 List<String> widgetIds = widgets.stream().map(Widget::getWidgetId).collect(Collectors.toList())... -
Your stream was neither an OLE2 stream, nor an OOXML stream
2019-12-03 10:35:44最近使用Apache poi 做excel导出的功能,遇到了如下问题: ...Your stream was neither an OLE2 stream, nor an OOXML stream 起初对比其他的web工程,没有发现如何解决。最后找到抛出此异常的源码: or... -
Spark Structured Stream的流关联(Stream-Stream Joins)
2018-08-01 10:48:04自Spark 2.3开始,Spark Structured Streaming开始支持Stream-stream Joins。两个流之间的join与静态的数据集之间的join有一个很大的不同,那就是,对于流来说,在任意时刻,在join的两边(也就是两个流上),数据都... -
使用H5Stream开发实时监控系统
2018-07-19 11:28:58这些天在尝试使用RTSP协议(Real Time Streaming Protocol,实时流传输协议)来完成实时传输和显示摄像头画面的功能,毕竟海康威视的web控件对高版本...H5Stream 在网上搜索web直播/摄像头直播等关键词找到了H5St... -
Stream流
2018-08-21 14:39:36Stream流 流式思想 流操作 获取流 常用方法 遍历:forEach 过滤:filter 映射:map Stream流 流式思想 Stream流是一个集合元素的函数模型,并不是集合,也不是数据结构,其本身并不存储... -
Lambda表达式最佳实践(2)Stream与ParallelStream
2018-02-01 14:57:48Stream是Java8新引入的API,有着广泛的运用 创建一个Stream Stream创建之后,就不能修改 创建一个空的Stream StreamString> streamEmpty = Stream.empty(); 一般的,我们用如下这种写法避免空指针异常 ...
-
30个生涯锦囊,带你跳出迷茫,找到适合你的职业方向
-
智慧文化旅游平台 .doc
-
真牛!史上最全的《Android面试题及解析》,震撼来袭免费下载!
-
【数据分析-随到随学】Python语法强化与数据处理
-
Codeforces Round #696 (Div. 2) 补题。
-
RabbitMQ消息中间件实战(附讲义和源码)
-
Kotlin协程极简入门与解密
-
计算器.vi(基于labview的简易计算器设计,可用于课程设计)
-
C#文件传输、Socket通信、大文件断点续传
-
大数据Hive on MR/TEZ与hadoop的整合应用
-
Python-标识符的命名规则与规范
-
three.js入门速成
-
疯狂涨知识!做了3年Android还没看过OkHttp源码?看看这篇文章吧!
-
微信支付2021系列之扫码支付一学就会java版
-
配置Xampp及本地域名.txt
-
【2021】UI自动化测试框架(Selenium3)
-
中国科学院大学《矩阵代数》期末考试试题.pdf
-
爆赞!我阿里P7了解到的Android面试的一些小内幕!Android校招面试指南
-
【数据分析-随到随学】Spark理论及实战
-
信息化和自动化(PLC)间XOR校验传输数据准确性