流式循环(forEach)中使用 brak、continue
创建循环操作类(LoopOperator)
创建循环操作专属异常类
原因: 用于标准流式 forEach 中,跳出循环作用。避免执行完 loopBreak()、loopContinue() 方法后,业务代码继续往后执行。在外部使用 try…catch… 捕获这个异常,从而跳出循环并停止执行后续代码
public static class LoopException extends RuntimeException{
private final String loopId;
public LoopException(String loopId, String message) {
super(message);
this.loopId = loopId;
}
public String getLoopId(){
return loopId;
}
}
创建 break 功能方法: loopBreak()
/**
* 结束本轮循环
*/
public void loopBreak() {
loopStopFlag.set(true);
// 终止流式处理,防止后续代码继续执行
throw new LoopException(loopId, "结束本轮循环");
}
创建 continue 功能方法: loopContinue()
/**
* 结束本次循环
*/
public void loopContinue() {
// 终止流式处理,防止后续代码继续执行
throw new LoopException(loopId, "结束本次循环");
}
完整代码如下
import java.util.concurrent.atomic.AtomicBoolean;
public class LoopOperator {
private final AtomicBoolean loopStopFlag = new AtomicBoolean(false);
private final String loopId = IdUtil.genId();
/**
* 结束本轮循环
*/
public void loopBreak() {
loopStopFlag.set(true);
// 终止流式处理,防止后续代码继续执行
throw new LoopException(loopId, "结束本轮循环");
}
/**
* 结束本次循环
*/
public void loopContinue() {
// 终止流式处理,防止后续代码继续执行
throw new LoopException(loopId, "结束本次循环");
}
public boolean getLoopStopFlag() {
return loopStopFlag.get();
}
public String getLoopId(){
return loopId;
}
public static class LoopException extends RuntimeException{
private final String loopId;
public LoopException(String loopId, String message) {
super(message);
this.loopId = loopId;
}
public String getLoopId(){
return loopId;
}
}
}
集合处理帮助类(CollectionUtils)
定义流式循环 forEach 方法
-
参数列表
- 数据集合 collection
- 函数式接口 BiConsumer<数据子项,循环操作对象>
-
扩展 foreach
使用标准 forEach 循环,添加扩展实现。
/**
* 流式遍历循环,提供流式循环的 break、continue 操作
* break: operator.loopBreak();
* continue: operator.loopContinue();
*
* @param collection 数据集
* @param biConsumer 消费逻辑
* @param <T> 数据类型
*/
public static <T> void forEach(Collection<T> collection, BiConsumer<T, LoopOperator> biConsumer){
if(isEmpty(collection)){
return;
}
LoopOperator loopOperator = new LoopOperator();
collection.forEach(item->{
// break 逻辑实现
if(loopOperator.getLoopStopFlag()){
return;
}
try{
biConsumer.accept(item, loopOperator);
}catch (LoopOperator.LoopException exception){
if(!exception.getLoopId().equals(loopOperator.getLoopId())){
throw exception;
}
}
});
}
完整代码如下
package com.zebra.utils;
import com.zebra.utils.pojo.LoopOperator;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class CollectionUtils {
/**
* 集合是否为空
* @param collection 数据集
* @return 是否为空
* @param <T> 数据类型
*/
public static <T> boolean isEmpty(Collection<T> collection){
return null == collection || collection.isEmpty();
}
/**
* 标注流式循环
* @param collection 数据集
* @param consumer 消费逻辑
* @param <T> 数据类型
*/
public static <T> void forEach(Collection<T> collection, Consumer<T> consumer){
forEach(collection,(item, loopOperator)->{
consumer.accept(item);
});
}
/**
* 流式遍历循环,提供流式循环的 break、continue 操作
* break: operator.loopBreak();
* continue: operator.loopContinue();
*
* @param collection 数据集
* @param biConsumer 消费逻辑
* @param <T> 数据类型
*/
public static <T> void forEach(Collection<T> collection, BiConsumer<T, LoopOperator> biConsumer){
if(isEmpty(collection)){
return;
}
LoopOperator loopOperator = new LoopOperator();
collection.forEach(item->{
// break 逻辑实现
if(loopOperator.getLoopStopFlag()){
return;
}
try{
biConsumer.accept(item, loopOperator);
}catch (LoopOperator.LoopException exception){
if(!exception.getLoopId().equals(loopOperator.getLoopId())){
throw exception;
}
}
});
}
}
测试案例
import com.zebra.utils.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class LoopTest {
public static void main(String[] args) {
List<Integer> list = IntStream.range(1, 10).boxed().collect(Collectors.toList());
CollectionUtils.forEach(list,(item,operator)->{
if(item % 3 == 0){
operator.loopContinue();
}
if (item == 8){
operator.loopBreak();
}
System.out.println(item);
});
}
}
结果输出
1
2
4
5
7
集合处理帮助类(MapUtils)
@FunctionalInterface
public interface ThreeConsumer<F, S, T> {
void accept(F first, S second, T three);
}
package com.zebra.utils;
import com.zebra.utils.pojo.LoopOperator;
import com.zebra.utils.pojo.ThreeConsumer;
import java.util.Map;
import java.util.function.BiConsumer;
public class MapUtils {
/**
* map是否为空
*
* @param map 数据集
* @param <K> 键类型
* @param <V> 值类型
* @return 是否为空
*/
public static <K, V> boolean isEmpty(Map<K, V> map) {
return null == map || map.isEmpty();
}
/**
* 标注流式循环
*
* @param map 数据集
* @param consumer 消费逻辑
* @param <K> 键类型
* @param <V> 值类型
*/
public static <K, V> void forEach(Map<K, V> map, BiConsumer<K, V> consumer) {
forEach(map, (key, value, loopOperator) -> {
consumer.accept(key, value);
});
}
/**
* 流式遍历循环,提供流式循环的 break、continue 操作
* break: operator.loopBreak();
* continue: operator.loopContinue();
*
* @param map 数据集
* @param operatorConsumer 消费逻辑
* @param <K> 键类型
* @param <V> 值类型
*/
public static <K, V> void forEach(Map<K, V> map, ThreeConsumer<K, V, LoopOperator> operatorConsumer) {
if (isEmpty(map)) {
return;
}
LoopOperator loopOperator = new LoopOperator();
map.forEach((key, value) -> {
// break 逻辑实现
if (loopOperator.getLoopStopFlag()) {
return;
}
try {
operatorConsumer.accept(key, value, loopOperator);
} catch (LoopOperator.LoopException exception) {
if(!exception.getLoopId().equals(loopOperator.getLoopId())){
throw exception;
}
}
});
}
}