怎么break java8 stream的foreach
怎么break java8 stream的foreach
简介
我们通常需要在java stream中遍历处理里面的数据,其中foreach是最最常用的方法。
但是有时候我们并不想处理完所有的数据,或者有时候Stream可能非常的长,或者根本就是无限的。
一种方法是先filter出我们需要处理的数据,然后再foreach遍历。
那么我们如何直接break这个stream呢?今天本文重点讲解一下这个问题。
使用Spliterator
上篇文章我们在讲Spliterator的时候提到了,在tryAdvance方法中,如果返回false,则Spliterator将会停止处理后续的元素。
通过这个思路,我们可以创建自定义Spliterator。
假如我们有这样一个stream:
Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
我们想定义一个操作,当x > 5的时候就停止。
我们定义一个通用的Spliterator:
public class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private Spliterator<T> splitr;
private Predicate<T> predicate;
private volatile boolean isMatched = true;
public CustomSpliterator(Spliterator<T> splitr, Predicate<T> predicate) {
super(splitr.estimateSize(), 0);
this.splitr = splitr;
this.predicate = predicate;
}
@Override
public synchronized boolean tryAdvance(Consumer<? super T> consumer) {
boolean hadNext = splitr.tryAdvance(elem -> {
if (predicate.test(elem) && isMatched) {
consumer.accept(elem);
} else {
isMatched = false;
}
});
return hadNext && isMatched;
}
}
在上面的类中,predicate是我们将要传入的判断条件,我们重写了tryAdvance,通过将predicate.test(elem)加入判断条件,从而当条件不满足的时候返回false.
看下怎么使用:
@Slf4j
public class CustomSpliteratorUsage {
public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) {
CustomSpliterator<T> customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);
return StreamSupport.stream(customSpliterator, false);
}
public static void main(String[] args) {
Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result =
takeWhile(ints, x -> x < 5 )
.collect(Collectors.toList());
log.info(result.toString());
}
}
我们定义了一个takeWhile方法,接收Stream和predicate条件。
只有当predicate条件满足的时候才会继续,我们看下输出的结果:
[main] INFO com.flydean.CustomSpliteratorUsage - [1, 2, 3, 4]
自定义forEach方法
除了使用Spliterator,我们还可以自定义forEach方法来使用自己的遍历逻辑:
public class CustomForEach {
public static class Breaker {
private volatile boolean shouldBreak = false;
public void stop() {
shouldBreak = true;
}
boolean get() {
return shouldBreak;
}
}
public static <T> void forEach(Stream<T> stream, BiConsumer<T, Breaker> consumer) {
Spliterator<T> spliterator = stream.spliterator();
boolean hadNext = true;
Breaker breaker = new Breaker();
while (hadNext && !breaker.get()) {
hadNext = spliterator.tryAdvance(elem -> {
consumer.accept(elem, breaker);
});
}
}
}
上面的例子中,我们在forEach中引入了一个外部变量,通过判断这个外部变量来决定是否进入spliterator.tryAdvance方法。
看下怎么使用:
@Slf4j
public class CustomForEachUsage {
public static void main(String[] args) {
Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result = new ArrayList<>();
CustomForEach.forEach(ints, (elem, breaker) -> {
if (elem >= 5 ) {
breaker.stop();
} else {
result.add(elem);
}
});
log.info(result.toString());
}
}
上面我们用新的forEach方法,并通过判断条件来重置判断flag,从而达到break stream的目的。
总结
本文通过两个具体的例子讲解了如何break一个stream,希望大家能够喜欢。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/break-stream-foreach
欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com
怎么break java8 stream的foreach的更多相关文章
- java8 Stream的实现原理 (从零开始实现一个stream流)
1.Stream 流的介绍 1.1 java8 stream介绍 java8新增了stream流的特性,能够让用户以函数式的方式.更为简单的操纵集合等数据结构,并实现了用户无感知的并行计算. 1.2 ...
- 如何用Java8 Stream API找到心仪的女朋友
传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量. 而Java8 Stream API 可以极大简化这一操作,代码行数少,且 ...
- java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)
当有一个List列表是无序的,List中的数据有parentid进行关联,通过java排序成两种排序类型: 所用的测试列表最顶级无parentid,若为特殊值,修改下判断方法即可. 第一种排序:按照树 ...
- 简洁又快速地处理集合——Java8 Stream(下)
上一篇文章我讲解 Stream 流的基本原理,以及它与集合的区别关系,讲了那么多抽象的,本篇文章我们开始实战,讲解流的各个方法以及各种操作 没有看过上篇文章的可以先点击进去学习一下 简洁又快速地处理集 ...
- 简洁又快速地处理集合——Java8 Stream(上)
Java 8 发布至今也已经好几年过去,如今 Java 也已经向 11 迈去,但是 Java 8 作出的改变可以说是革命性的,影响足够深远,学习 Java 8 应该是 Java 开发者的必修课. 今天 ...
- java8 Stream使用总结
[前言] java8新特性 java8 函数接口 java8 Optional使用总结 Java 8 时间日期使用 java8 lambda表达式 1.流的介绍 Java8 中的 Stream 是对集 ...
- Java8 Stream新特性详解及实战
Java8 Stream新特性详解及实战 背景介绍 在阅读Spring Boot源代码时,发现Java 8的新特性已经被广泛使用,如果再不学习Java8的新特性并灵活应用,你可能真的要out了.为此, ...
- 【转】Java8 Stream 流详解
当我第一次阅读 Java8 中的 Stream API 时,说实话,我非常困惑,因为它的名字听起来与 Java I0 框架中的 InputStream 和 OutputStream 非常类似.但是 ...
- 何用Java8 Stream API进行数据抽取与收集
上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据 ...
随机推荐
- vulnhub~sunset:dusk1
晚上闲来无事,准备做个target,结果是各种错误.在睡觉前还是没有顺利的做出来.先将TroubleSHOOTing 总结如下: 在用hydra爆破mysql的时候,发现 'MySql Host is ...
- Jmeter 压力测试笔记(2)--问题定位
事情已经出了,是该想办法解决的时候了. 经过运维和DBA定位: 数据库读写分离中,读库延时超过了30秒,导致所有请求都压在主库.另外所有数据库都连接数都被占满,但活跃请求数量缺不多. 数据库16K的连 ...
- Struts2-学习笔记系列(3)-返回视图
Action执行execute返回字符串,又如何返回对应的页面呢? 关在在于struts中action节点配置的result.如下: 内置有的ERROR SUCCESS等好几种.看源码即可 publ ...
- networkx学习与攻击转移图可视化
接到一个任务,将攻击转移矩阵进行可视化,生成攻击转移概率图,便尝试用python实现一下. 查阅资料,看大家都在用networkx和matplotlib进行可视化,便边学边做,记录一下学习笔记. 任务 ...
- Codeup 25593 Problem G 例题5-7 求圆周率pi的近似值
题目描述 用如下公式 4*Π = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 - 求圆周率PI的近似值,直到发现某一项的绝对值小于10-6为止(该项不 ...
- 【three.js第五课】光线的添加和感光材料
材料分类: MeshBasicMaterial:基础网孔材料,一个以简单着色(平面或线框)方式来绘制几何形状的材料.MeshLambertMaterial:兰伯特网孔材料,一种非发光材料(兰伯特)的表 ...
- 教你如何在工作中“偷懒”,python优雅的帮你解决
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取htt ...
- stand up meeting 12-11
今天因组员时间问题,并没有集中在一起开会,但士杰当面和天赋同学进行了沟通,在lync与国庆进行了沟通. 天赋与重阳再次进行了了沟通,确定了“单词挑战”与“背单词”这两个模块集成的难度,决定先不进行集成 ...
- Sprint 3 : oxford project API 尝试
本次Sprint我们大家主要在调研和尝试阶段,主要是对photo experience 中的语音接口部分进行相应的调研和分析. 工作进度: 1. 图像界面设计兆阳和敏龙的工作进一步推进,除去之前介绍的 ...
- Joomla 3.4.6 Remote Code Execution漏洞复现
0x00:简介 Joomla是一套全球有名的CMS系统. Joomla基于PHP语言加上MySQL数据库所开发出来的WEB软件系统,目前最新版本是3.9.12. Joomla可以在多种不同的平台上部署 ...