在列表中合并树图

时间:2014-06-25 22:03:30

标签: java

我有List<Map<String, Object>>,其中包含以下地图。

Map:{clusterList=[71051], senseId=65786, totalCluster=1}
Map:{clusterList=[71051], senseId=65787, totalCluster=1}
Map:{clusterList=[4985, 71052], senseId=65788, totalCluster=2}
Map:{clusterList=[125840,153610,167812, 65787, 204091, 32586, 65786], senseId=71051, totalCluster=7}
Map:{clusterList=[11470, 65788], senseId=71052, totalCluster=2} 

我遍历了地图并检查了是否在clusterList中存在senseId。但是使用senseId遍历每个clusterList需要很长时间才能使用传统的for循环,而且我无法将合并列表作为以下内容获取

Map:{clusterList=[125840,153610,167812, 65787, 204091, 32586, 65786], senseId=71051, totalCluster=7}
Map:{clusterList=[4985,11470, 65788], senseId=71052, totalCluster=2}

我甚至无法删除clusterList中存在sensId的地图,因为它会抛出并发操作异常。

任何想法如何获得除了for循环之外的结果,因为此列表非常小,因此循环仍然有效。但是我有180个地图条目的列表,很难遍历整个列表并合并地图。

我被卡住了,因为一张地图的senseId出现在其他地图的clusterList中。因此无法将它们与简单搜索合并。

1 个答案:

答案 0 :(得分:1)

我很确定问题仍未明确。例如,目前尚不清楚如何决定最终的senseId。当你有两张地图时

Map:{clusterList=[123,456,789], senseId=123, totalCluster=1}
Map:{clusterList=[123,456,666], senseId=456, totalCluster=1}

然后(如果我理解正确的话)他们应该合并。但目前尚不清楚结果是否应该是地图

Map:{clusterList=[123,456,789,666], senseId=123, totalCluster=1}

或地图

Map:{clusterList=[123,456,789,666], senseId=456, totalCluster=1}

除此之外,似乎“totalCluster”是群集列表的大小。这意味着它很可能是不必要的,如果不必要,则必须指定在合并两个地图时应如何处理它。

但是,这是一个基本方法:可以创建从senseId到使用此senseId的地图的地图,然后在其群集列表中收集包含特定senseId的地图为了找出哪些地图必须合并。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


public class MapMergeTest
{
    public static void main(String[] args)
    {
        List<Map<String, Object>> maps = createInput();

        System.out.println("Input:");
        for (Map<String, Object> map : maps)
        {
            System.out.println(map);
        }

        List<Map<String, Object>> result = createMergedMapsList(maps);

        System.out.println("Result:");
        for (Map<String, Object> map : result)
        {
            System.out.println(map);
        }
    }


    private static List<Map<String, Object>> createInput()
    {
        List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
        //                senseId  clusterList...
        maps.add(createMap(65786,  71051));
        maps.add(createMap(65787,  71051));
        maps.add(createMap(65788,  4985, 71052));
        maps.add(createMap(71051,  125840, 153610, 167812, 
            65787, 204091, 32586, 65786));
        maps.add(createMap(71052,  11470, 65788));
        return maps;
    }
    private static Map<String, Object> createMap(
        Integer senseId, Integer ... clusters)
    {
        Map<String, Object> result = new LinkedHashMap<String, Object>();
        result.put("senseId", senseId);
        result.put("clusterList", new ArrayList<Integer>(Arrays.asList(clusters)));
        return result;
    }



    private static List<Map<String, Object>> createMergedMapsList(
        List<Map<String, Object>> maps)
    {
        Map<Integer, Map<String, Object>> senseIdToMap =
            createSenseIdToMap(maps);

        Map<Integer, Map<String, Object>> copy = 
            new LinkedHashMap<Integer, Map<String,Object>>(senseIdToMap);
        for (Entry<Integer, Map<String, Object>> e : copy.entrySet())
        {
            Integer senseId = e.getKey();
            Map<String, Object> map = e.getValue();
            List<Integer> clusterList = getClusterList(map);
            List<Map<String, Object>> mapsToMerge = 
                new ArrayList<Map<String,Object>>();
            mapsToMerge.add(map);
            for (Integer cluster : clusterList)
            {
                Map<String, Object> mapToMerge =
                    senseIdToMap.get(cluster);
                if (mapToMerge != null)
                {
                    mapsToMerge.add(mapToMerge);
                    senseIdToMap.remove(cluster);
                }
            }
            if (mapsToMerge.size() > 1)
            {
                Map<String, Object> mergedMap = mergeMaps(mapsToMerge);
                List<Integer> mergedClusterList = getClusterList(mergedMap);
                mergedClusterList.remove(senseId);
                senseIdToMap.put(senseId, mergedMap);
            }
        }
        return new ArrayList<Map<String,Object>>(senseIdToMap.values());
    }

    private static Map<Integer, Map<String, Object>> createSenseIdToMap(
        List<Map<String, Object>> maps)
    {
        Map<Integer, Map<String, Object>> senseIdToMap = 
            new LinkedHashMap<Integer, Map<String,Object>>();
        for (Map<String, Object> map : maps)
        {
            Integer senseId = (Integer)map.get("senseId");
            senseIdToMap.put(senseId, map);
        }
        return senseIdToMap;
    }

    private static Map<String, Object> mergeMaps(List<Map<String, Object>> list)
    {
        Map<String, Object> mergedMap = new LinkedHashMap<String, Object>();
        Map<String, Object> firstMap = list.get(0);
        mergedMap.put("senseId", firstMap.get("senseId"));
        Set<Integer> mergedClusterList = new LinkedHashSet<Integer>();
        for (Map<String, Object> map : list)
        {
            List<Integer> clusterList = getClusterList(map);
            mergedClusterList.addAll(clusterList);
        }
        mergedMap.put("clusterList", new ArrayList<Integer>(mergedClusterList));
        return mergedMap;
    }


    private static List<Integer> getClusterList(Map<String, Object> map)
    {
        Object object = map.get("clusterList");
        return (List<Integer>)object;
    }

}