Java分割集合 Java分割 list java分割集合 java分割list Java 平均分割集合列表

Java分割集合 Java分割 list java分割集合 java分割list Java 平均分割集合列表

需求,生产二维码内容有限制,并且 内容过多,会导致二维码很臃肿 扫描不出来,之前是用 谷歌的 Lists.partition,但是还有一个问题就是,分割好的集合数量不均匀,比如 300个文字,一个集合最多存放200个字,就会出现 一个集合 有200个,一个集合只有100个,这种,我想要的是 两个集合 都是平均数量 只有 150个

纯Java jdk实现

静态工具类

import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <h2>集合工具类</h2>
 * <p>
 *
 * </p>
 *
 * @author <1922802352@qq.com>
 * @since 2022年12月29日 16:15
 */
public class MyListUtil {
	/**
	 * 按照指定数量分割集合
	 *
	 * @param list 需要分割的集合
	 * @param size 一个集合最多数量
	 * @return List<List < T>>
	 */
	public static <T> List<List<T>> partition(List<T> list, int size) {
		
		// 一个集合最多数量
		BigDecimal singleListCount = new BigDecimal(size);
		
		// 当前集合总数量
		BigDecimal nowAllCount = new BigDecimal(list.size());
		
		// 分割集合数量 = 总数量 / 当个集合最多数量, 值始终要五入,例如 当个集合最多100,总数量是120个,那么需要两个集合
		int listCount = nowAllCount.divide(singleListCount, 0, RoundingMode.UP).intValue();
		
		// 创建 分割集合
		List<List<T>> partitionList = new ArrayList<>();
		for (int i = 0; i < listCount; i++) {
			// 截取集合开始下标
			int start = i * size;
			// 截取集合结束下标
			int end = Math.min(start + size, list.size());
			// 使用开始结束小标截取集合
			List<T> child = list.subList(start, end);
			partitionList.add(child);
		}
		return partitionList;
	}
	
	/**
	 * 按照指定数量分割集合, 每个集合的数量是平均大小的
	 *
	 * @param list 需要分割的集合
	 * @param size 一个集合最多数量
	 * @return List<List < T>>
	 */
	public static <T> List<List<T>> partitionByAvg(List<T> list, int size) {
		
		// 一个集合最多数量
		BigDecimal singleListCount = new BigDecimal(size);
		
		// 当前集合总数量
		BigDecimal nowAllCount = new BigDecimal(list.size());
		
		// 分割集合数量 = 总数量 / 当个集合最多数量, 值始终要五入,例如 当个集合最多100,总数量是120个,那么需要两个集合
		
		int listCount = nowAllCount.divide(singleListCount, 0, RoundingMode.UP).intValue();
		
		// 创建 分割集合
		List<List<T>> partitionList = new ArrayList<>();
		for (int i = 0; i < listCount; i++) {
			partitionList.add(new ArrayList<>());
		}
		
		// 计算 一个集合平均数量,避免出现 两个集合,一个集合有150个,另外一个集合只有1个的现象
		
		int avg = list.size() / listCount;
		
		// 将数据平均放入 分割好的集合中
		for (T s : list) {
			// 遍历放入分割好的集合
			for (int i = 0; i < listCount; i++) {
				if (partitionList.get(i).size() < avg) {
					partitionList.get(i).add(s);
					break;
				}
			}
		}
		return partitionList;
	}
	
	/**
	 * 将源List按照指定元素数量拆分为多个List
	 *
	 * @param source       源List
	 * @param splitItemNum 每个List中元素数量
	 */
	public static <T> List<List<T>> averageAssign(List<T> source, int splitItemNum) {
		List<List<T>> result = new ArrayList<>();
		
		if (source != null && source.size() > 0 && splitItemNum > 0) {
			if (source.size() <= splitItemNum) {
				// 源List元素数量小于等于目标分组数量
				result.add(source);
			} else {
				// 计算拆分后list数量
				int splitNum = (source.size() % splitItemNum == 0) ? (source.size() / splitItemNum) : (source.size() / splitItemNum + 1);
				
				List<T> value;
				for (int i = 0; i < splitNum; i++) {
					if (i < splitNum - 1) {
						value = source.subList(i * splitItemNum, (i + 1) * splitItemNum);
					} else {
						// 最后一组
						value = source.subList(i * splitItemNum, source.size());
					}
					result.add(value);
				}
			}
		}
		return result;
	}
	
	public static boolean isEmpty(Collection<?> list) {
		return CollectionUtils.isEmpty(list);
	}
	
	public static boolean isNotEmpty(Collection<?> list) {
		return !CollectionUtils.isEmpty(list);
	}
	
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("4");
		list.add("5");
		list.add("6");
		list.add("7");
		list.add("8");
		List<List<String>> partition = MyListUtil.partition(list, 5);
		partition.forEach(l -> l.forEach(c -> System.out.printf("不平均分割集合,当前集合数量:%s, 遍历值:%s \n\r", l.size(), c)));
		
		List<List<String>> partitionAvg = MyListUtil.partitionByAvg(list, 5);
		partitionAvg.forEach(l -> l.forEach(c -> System.out.printf("平均分割集合,当前集合数量:%s, 遍历值:%s \n\r", l.size(), c)));
		
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值