批量移除匹配的List对象

背景

所有的代码功能实现都是对业务需求的实现,脱离业务的展示肌肉方式不可行。

最近有个业务需求,因为B业务的数据来源于C表和D表。因为B中把C和D的ID存放到了一个字段,然后加了个类型字段进行了区分。

当C表和D表的数据删除后,B表的数据需要同步进行删除操作。

思路

1、最简单的方法。

直接在C表和D表的相关Service实现中,在删除的方法中增加对应的删除B业务的数据代码就可以了。

总结

简单、粗暴、高效(在开发的角度上来看),但是代码侵入性较大,后期维护拆分的时候有点痛苦。

2、使用切面。

在C和D的删除方法上使用注解,然后在注解里面更新。

总结

优秀,但是业务涉及面较窄,开发工作量相对较大一些。

3、使用定时器

总结

业务拆分,定时器里可以根据业务进行动态的调整,相对来讲,比较符合当前的业务。

解决

实现思路

回到我们的解决思路来:根据我们的业务来看,我们刚开始查询出来的数据是一个B列表对象。然后再去根据类型筛选出来对应的C和D有效数据,然后再使用当前B数据对象去匹配删除有效数据。剩下的都是无效数据,把无效数据批量删除就可以了。

伪代码

先上伪代码(翻译上面那段啰嗦的话)

//1、获取B的所有有效数据
List<B> listB= selectListB();

//2、分类,根据分类结果来查对应的C和D
List<Long,List<B>> map = listB.stream().collect(Collectors.groupingBy(B::getType));

//3、循环map 根据类型来查出对应的C和D的数据
map.forEach((k, v) -> {
    if (类型==C) {
        List<C> listC=selectListC(v->List<B>中获取相关的查询条件的CId)
        //删除有效数据
        listB.removeIf(listC对应的所有有效数据)
    } else {
        List<D> listD=selectListD(v->List<B>中获取相关的查询条件的DId)
        //删除有效数据
        listB.removeIf(listD对应的所有有效数据)
    }
 });

//4、批量删除 剩下来的listB就是无效数据了
deleteBatchB(listB)

在这个里面,主要是用到了stream的新的特性相关方法,主要就是用来批量删除子对象。这样剩下的战斗渣渣就可以使用批量删除,减少了和数据库的沟通次数了。

removeIf方法

着重介绍下removeIf方法。removeIf() 方法作用是用于删除所有满足特定条件的数组元素。

老规矩,先看源码

    /**
     * Removes all of the elements of this collection that satisfy the given
     * predicate.  Errors or runtime exceptions thrown during iteration or by
     * the predicate are relayed to the caller.
     *
     * @implSpec
     * The default implementation traverses all elements of the collection using
     * its {@link #iterator}.  Each matching element is removed using
     * {@link Iterator#remove()}.  If the collection's iterator does not
     * support removal then an {@code UnsupportedOperationException} will be
     * thrown on the first matching element.
     *
     * @param filter a predicate which returns {@code true} for elements to be
     *        removed
     * @return {@code true} if any elements were removed
     * @throws NullPointerException if the specified filter is null
     * @throws UnsupportedOperationException if elements cannot be removed
     *         from this collection.  Implementations may throw this exception if a
     *         matching element cannot be removed or if, in general, removal is not
     *         supported.
     * @since 1.8
     */
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

方法说明

参数说明:

   filter - 过滤器,判断元素是否要删除

返回值

  如果元素被删除则返回 true。

使用场景

伪代码中的listB.removeIf(listC对应的所有有效数据)的这个的实现就用到了

代码

listB.removeIf(listC对应的所有有效数据)
//代码实现
listB.removeIf(e -> listC.stream().map(C::getId).collect(Collectors.toList()).contains(e.getTypeId()));

//说明:getTypeId这个是B中存放的C的主键ID

使用这个的好处,就是我们可以复用一个对象,打野中路,减少内存的输出伤害!

总结说明

代码是为业务服务的。没有最好的实现方法,只有最符合当前的业务模式的实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值