我们公司的工具类ComputeUtil之关于集合的分割(或者说折叠)方法splitList

在公司写代码的时候看到老员工用到一个工具类,看不懂作用但大为震撼。据称是我们技术经理写的。不知道有什么用,于是拿去偷偷请教药老,药老看了三分钟,告诉我原来是这么一回事,先上代码:

/**
 * 集合分割
 * @param collection 集合
 * @param splitSize 分割条件, eg,1000个元素按照100分隔,则splitSize=100
 * @param <T> 元素类型
 * @author hult
 * @return <T> List<Collection>
 */
public static <T> List<Collection>  splitList(Collection<T> collection, int splitSize) {
    if (collection.isEmpty()) {
        return Collections.emptyList();
    }
    int splitCount = (collection.size() + splitSize - 1)  / splitSize;
    return Stream.iterate(0, n -> n + 1)
            .limit(splitCount)
            .parallel()
            .map(index -> collection.stream().skip((long)index * splitSize).limit(splitSize).collect(Collectors.toList()))
            .filter(s -> !s.isEmpty())
            .collect(Collectors.toList());
}

首先要明白这个方法到底想干嘛?

假设这样一个场景,用户浏览页面数据,你用了mybatisPlus进行了分页,用户想要得到10条数据,而后端设置的最大请求参数值是5条数据,而用户在前端请求过来的是10个数据。那这10条数据经过这个ComputeUtil.splitList(Collection<T> collection, int splitSize)方法,其实是把这10条数据折叠起来了(为了满足你的设置的最大请求数是5的要求嘛),把一个一维数组变成了二维数组。如下图:

现在是不是有两个list?

用户传过来了0123456789,他想要的数据是这样的,但是我们设置了一个最大值是5,就不允许他一次十条的处理,为什么这么做呢?

药老猜测说可能是为了性能上的考虑,把它拆分开,可能性能上会好一点,并且还可以节省点内存,避免出现内存溢出。

这个方法会返回一个大list,里面装了两个小list,此所谓折叠。这个方法返回的大list,长度为2,元素对象为两个小list,然后每个小list里面的长度都是5

 下图为所见部分代码截图:

@Override
public List<BusinessUnitExamine> queryByUnitIds(List<String> businessIds) {
    if (businessIds.isEmpty()) {
        return new ArrayList<>();
    }
    int maxSize = 1000;
    if (businessIds.size() < maxSize) {
        return new LambdaQueryChainWrapper<>(mapper)
                .in(BusinessUnitExamine::getAssociateId, businessIds)
                .list();
    }
    return ComputeUtil.splitList(businessIds, maxSize)
            .stream()
            .map(childIds -> new LambdaQueryChainWrapper<>(mapper)
                    .in(BusinessUnitExamine::getAssociateId, childIds)
                    .list()
            )
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
}

里面的childIds是什么意思呢?对于返回的二维数组又做了一个stream流处理,childIds对应每一个list1和list2。这里相当于把一次查询分成了两次查询,然后从数据库里查出来是in在businessUnitExamine.getAssociateId或者是childIds里边。先查在businessUnitExamine.getAssociateId里边再查在childIds里边,最后把查出来的结果反折叠(用flatMap)再转成lit,就是不是又把一个二维数组处理成了一个一维数组?

这样做的好处?
1、提高性能(我一块一块的去处理,总比我一起去处理总要好的)
2、节省内存,避免出现内存溢出(这个为最主要的作用)

为什么说要避免内存溢出呢?

咱们的服务器都是有内存上限的。比如说有一个G的内存,那么我们最多申请用到1024MB的空间。那这样经过工具类去进行分割折叠处理的话,我可以去反复的利用这1024M空间内存,就不用每次一开始就申请全部的1024M空间。

好了,今天的新知就学到这里了,那么,坐在屏幕前的你,学废了吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值