怎么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 如何抽取及收集数据 ...
随机推荐
- 【python系统学习13】类(class)与对象(object)
目录: 类(class)和实例 类 实例 小测试 对象(object) 属性和方法 类的创建 伪代码 示例代码 属性(attribute) 方法(method) 类的实例化 实例对象调用类属性和方法 ...
- 在vue+elementUI项目中使用分页功能
HTML: <div class="mRttt"> <!-- 分页 --> <el-pagination ...
- 分治与递归-Starssen矩阵乘法
代码实现: /** * 矩阵乘法求解 * @author Administrator * */ public class Strassen { public static final int NUMB ...
- Python:Day05-2
面向对象进阶 在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息.为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程 ...
- 关于微信小程序的一点经验
2018年的11月份,自己做微信小程序相关的项目已经有四个月,这四个月自己走过很多弯路,也学到了不少经验,下面就一一总结: 一,微信小程序的radio组件是可以改变按钮样式的(比如大小,颜色等等) 改 ...
- 在.net core中完美解决多租户分库分表的问题
前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库 计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现 然而这个使 ...
- json格式的文件操作2
1.字典转换为字符串(json.dumps) jsongeshi={"name":"yajuan","age":"10" ...
- dp优化---四边形不等式与决策单调性
四边形不等式 定理1: 设w(x,y)为定义在整数集合上的二元函数,若存在任意整数a,b,c,d(a<=b<=c<=d),并且w(a,d)+w(b,c)>=w(a,c)+w(b ...
- Maybatis的一些总结(二:基本使用过程)
理清一下使用需要做的步骤 建项目,导入mybatis(3.5.2)和mysql(5.1.47)进pom.xml pom.xml需配置build时过滤器,否则会出现xml文件导出不了的问题 resour ...
- OS X10.10.3正式版和Xcode 6.3正式版下载
4.09日,OS X10.10.3 正式版 IOS8.3 正式版和 Xcode 6.3 正式版在今天发布,这是 2015 年里面,IOS 系统和 Mac OS 系统,以及 IOS 和 Mac OS 专 ...