流式循环(forEach)中使用 brak、continue 功能

流式循环(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 方法

  1. 参数列表

    • 数据集合 collection
    • 函数式接口 BiConsumer<数据子项,循环操作对象>
  2. 扩展 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;
            	}
            }
        });
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊森的代码园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值