Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在HashMap中反转键值对_Java_Arraylist_Hashmap - Fatal编程技术网

Java 在HashMap中反转键值对

Java 在HashMap中反转键值对,java,arraylist,hashmap,Java,Arraylist,Hashmap,我的数据结构如下: Map<String,ArrayList<String>> graph = new HashMap<String,ArrayList<String>>(); private Map<String,ArrayList<String>> reverseAdjList(Map<String,ArrayList<String>> adjList){ Map<String,A

我的数据结构如下:

Map<String,ArrayList<String>> graph = new HashMap<String,ArrayList<String>>();
private Map<String,ArrayList<String>> reverseAdjList(Map<String,ArrayList<String>> adjList){
    Map<String,ArrayList<String>> tGraph = new HashMap<String,ArrayList<String>>();
    for (Map.Entry<String, ArrayList<String>> entry : adjList.entrySet()) {
        String key = entry.getKey();
        ArrayList<String> values = new ArrayList<>();
        values.add(key);
        ArrayList<String> value = entry.getValue();    
        for(String v:value){
            if(tGraph.containsKey(v)){
                values.addAll(tGraph.get(v));
            }
            tGraph.put(v, values);
        }
    }
    return tGraph;
}
Map-graph=newhashmap();
这本质上是一个哈希映射,它将字符串值作为键,并将字符串数组列表存储在键的值中。 现在,我尝试反转键值模式,使value成为键,并使key成为值。我的做法如下:

Map<String,ArrayList<String>> graph = new HashMap<String,ArrayList<String>>();
private Map<String,ArrayList<String>> reverseAdjList(Map<String,ArrayList<String>> adjList){
    Map<String,ArrayList<String>> tGraph = new HashMap<String,ArrayList<String>>();
    for (Map.Entry<String, ArrayList<String>> entry : adjList.entrySet()) {
        String key = entry.getKey();
        ArrayList<String> values = new ArrayList<>();
        values.add(key);
        ArrayList<String> value = entry.getValue();    
        for(String v:value){
            if(tGraph.containsKey(v)){
                values.addAll(tGraph.get(v));
            }
            tGraph.put(v, values);
        }
    }
    return tGraph;
}
private Map reverseAdjList(映射调整列表){
Map tGraph=newhashmap();
对于(Map.Entry:adjList.entrySet()){
String key=entry.getKey();
ArrayList值=新的ArrayList();
值。添加(键);
ArrayList值=entry.getValue();
for(字符串v:值){
if(t图容器(v)){
values.addAll(tGraph.get(v));
}
tGraph.put(v,值);
}
}
返回tGraph;
}
因此,这对我来说非常有用,可以反转小数据集的哈希映射键-值模式,但是当我在遇到的较大数据集上尝试它时

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.addAll(ArrayList.java:579)
at GraphProcessor.reverseAdjList(GraphProcessor.java:67)
at GraphProcessor.SCC(GraphProcessor.java:135)
at GraphProcessor.<init>(GraphProcessor.java:50)
at GraphProcessor.main(GraphProcessor.java:250)
线程“main”java.lang.OutOfMemoryError中的异常:java堆空间 位于java.util.Arrays.copyOf(Arrays.java:3210) 位于java.util.Arrays.copyOf(Arrays.java:3181) 在java.util.ArrayList.grow(ArrayList.java:261) 在java.util.ArrayList.ensureExplicitCapacity处(ArrayList.java:235) 位于java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) 在java.util.ArrayList.addAll(ArrayList.java:579) 在GraphProcessor.reverseAdjList(GraphProcessor.java:67) 在GraphProcessor.SCC(GraphProcessor.java:135) 在GraphProcessor上。(GraphProcessor.java:50) 位于GraphProcessor.main(GraphProcessor.java:250)
我知道这是一种非常幼稚和错误的做法,什么是更好和正确的做法

您的代码中有一个错误:

for (Map.Entry<String, ArrayList<String>> entry : adjList.entrySet()) {
    String key = entry.getKey();
    ArrayList<String> values = new ArrayList<>(); // Wrong place for this variable.
    values.add(key);
    ArrayList<String> value = entry.getValue();    
    for(String v:value){
        if(tGraph.containsKey(v)){
            values.addAll(tGraph.get(v));
        }
        tGraph.put(v, values);
    }
}
但实际上,您不需要为每个内部
步骤创建新的列表实例。对于
步骤,请使用JDK 1.8尝试以下代码:

private  Map<String, List<String>> reverseMap(Map<String, List<String>> adjList) {
    Map<String, List<String>> tGraph = new HashMap<>();
    for (Map.Entry<String, List<String>> entry : adjList.entrySet()) {
        for (String value : entry.getValue()) {
            tGraph.computeIfAbsent(value, v -> new ArrayList<>()).add(entry.getKey()); // Updated according comment from @shmosel
        }
    }
    return tGraph;
}
私有映射反向映射(映射调整列表){
Map tGraph=newhashmap();
对于(Map.Entry:adjList.entrySet()){
for(字符串值:entry.getValue()){
tGraph.computeIfAbsent(value,v->new ArrayList()).add(entry.getKey());//根据@shmosel的注释更新
}
}
返回tGraph;
}
如果您使用的是较旧版本的jdk,可以尝试:

    private Map<String, List<String>> reverseMap(Map<String, List<String>> adjList) {
    Map<String, List<String>> tGraph = new HashMap<>();
    for (Map.Entry<String, List<String>> entry : adjList.entrySet()) {
        for (String value : entry.getValue()) {
            List<String> newValues = tGraph.get(value);
            if (newValues == null) {
                newValues = new ArrayList<>();
                tGraph.put(value, newValues);
            }
            newValues.add(entry.getKey());
        }
    }
    return tGraph;
}
私有映射反向映射(映射调整列表){
Map tGraph=newhashmap();
对于(Map.Entry:adjList.entrySet()){
for(字符串值:entry.getValue()){
List newValues=tGraph.get(值);
if(newValues==null){
newValues=newarraylist();
tGraph.put(值,newValues);
}
newValues.add(entry.getKey());
}
}
返回tGraph;
}

希望这能有所帮助:-)

您的数据集有多大?也许您只需要使用
-Xmx
增加jvm堆大小,因为您的代码是错误的<代码>值
对于每个键只实例化一次,并且对于每个值它都以指数形式增长。尝试移动
ArrayList value=new ArrayList()
到内部
进行
循环。更好的是,将
键添加到先前映射的列表中,而不是每次都复制。太棒了!非常感谢你把它修好了。还感谢您建议使用密钥。很抱歉,我通过尝试您的代码发现了您的错误,并将其作为答案发布,但shmosel对此进行了评论,答案中还包含一些重构想法,因此我决定保留它,希望它能有所帮助。没问题,我非常感谢您尝试帮助我@shizhz。非常感谢你,我发现你的回答很有帮助,而且解释得很好。非常感谢!这非常有帮助。@smriti非常乐意帮助:-)Java 8中更好的解决方案:
tGraph.computeifassent(value,v->new ArrayList()).add(entry.getKey())@shmosel,这真的很酷,非常感谢。我已经更新了答案:)