Java Map拆分成子Map

本文介绍了两个Map拆分方法:按指定分组大小和分组数量,适用于Java编程中高效处理数据,通过示例展示了如何将Map均匀分配到各个子Map中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.visy.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.util.*;

/**
 * @author visy.wang
 * @date 2022/1/26 9:39
 */
public class MapUtil {

    /**
     * Map拆分 (指定分组大小)
     * @param map Map
     * @param chunkSize 每个分组的大小 (>=1)
     * @param <K> Key
     * @param <V> Value
     * @return 子Map列表
     */
    public static <K,V> List<Map<K,V>> splitByChunkSize(Map<K,V> map, int chunkSize){
        if(Objects.isNull(map) || map.isEmpty() || chunkSize<1){
            //空map或者分组大小<1,无法拆分
            return Collections.emptyList();
        }

        int mapSize = map.size(); //键值对总数
        int groupSize = mapSize/chunkSize + (mapSize%chunkSize==0?0:1); //计算分组个数
        List<Map<K,V>> list = Lists.newArrayListWithCapacity(groupSize); //子Map列表

        if(chunkSize >= mapSize){ //只能分1组的情况
            list.add(map);
            return list;
        }

        int count = 0; //每个分组的组内计数
        Map<K,V> subMap = Maps.newHashMapWithExpectedSize(chunkSize); //子Map

        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (count < chunkSize) {
                //给每个分组放chunkSize个键值对,最后一个分组可能会装不满
                subMap.put(entry.getKey(), entry.getValue());
                count++; //组内计数+1
            } else {
                //结束上一个分组
                list.add(subMap); //当前分组装满了->加入列表

                //开始下一个分组
                subMap = Maps.newHashMapWithExpectedSize(chunkSize); //新的分组
                subMap.put(entry.getKey(), entry.getValue()); //添加当前键值对
                count = 1; //组内计数重置为1
            }
        }

        list.add(subMap);  //添加最后一个分组
        return list;
    }

    /**
     * Map拆分(指定分组个数)
     * @param map Map
     * @param groupSize 分组个数 (>=1)
     * @param <K> Key
     * @param <V> Value
     * @return 子Map列表
     */
    public static <K,V> List<Map<K,V>> splitByGroupSize(Map<K,V> map, int groupSize){
        if(Objects.isNull(map) || map.isEmpty() || groupSize<1){
            //空map或者分组数<1,无法拆分
            return Collections.emptyList();
        }

        List<Map<K,V>> list = Lists.newArrayListWithCapacity(groupSize);
        if(groupSize == 1){ //只有1个分组的情况
            list.add(map);
            return list;
        }

        int mapSize = map.size(); //键值对总数
        int chunkIndex = 0; //当前分组的下标,[0, groupSize-1]
        int restCount = mapSize % groupSize; //平均后剩余的键值对数
        int chunkSize0 = mapSize / groupSize; //每个分组键值对数量
        int chunkSize1 = chunkSize0 + 1; //多分一个
        int chunkSize = chunkIndex<restCount ? chunkSize1 : chunkSize0; //实际每组的大小(前面的部分分组可能会多分1个)
        int count = 0; //每个分组的组内计数
        Map<K,V> subMap = Maps.newHashMapWithExpectedSize(chunkSize);//子Map

        for (Map.Entry<K, V> entry : map.entrySet()) {
            if(count < chunkSize){
                //每个分组按实际分组大小(chunkSize)加入键值对
                subMap.put(entry.getKey(), entry.getValue());
                count ++; //组内计数+1
            }else{
                //结束上一个分组
                list.add(subMap); //当前分组装满了->加入列表
                chunkIndex ++; //分组个数+1

                //开始下一个分组
                chunkSize = chunkIndex<restCount ? chunkSize1 : chunkSize0; //重新计算分组大小
                subMap = Maps.newHashMapWithExpectedSize(chunkSize); //新的分组
                subMap.put(entry.getKey(), entry.getValue()); //添加当前键值对
                count = 1; //组内计数重置为1
            }
        }

        list.add(subMap); //添加最后一个分组
        return list;
    }

    //测试
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        map.put("a", "1");
        map.put("b", "2");
        map.put("c", "3");
        map.put("d", "4");
        map.put("e", "5");
        map.put("f", "6");
        map.put("g", "7");

        System.out.println("splitByChunkSize: " + splitByChunkSize(map, 3));
        System.out.println("splitByGroupSize: " + splitByGroupSize(map, 3));
    }
}

输出:

splitByChunkSize: [{a=1, b=2, c=3}, {d=4, e=5, f=6}, {g=7}]
splitByGroupSize: [{a=1, b=2, c=3}, {d=4, e=5}, {f=6, g=7}]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值