作为对象的HashMap值具有被错误的值覆盖的属性

时间:2018-12-21 08:32:43

标签: java hashmap

我正在遍历具有对象作为值和字符串作为键的哈希图。

 ResultSet myresults = st.executeQuery("SELECT traces.* from traces");

    while (myresults.next()) {
        MethodTrace MethodTrace = new MethodTrace();
        Method method= new Method(); 
        Requirement requirement= new Requirement(); 



 requirement=RequirementHashMap.get(myresults.getString("requirementid")); 
         method = MethodHashMap.get(myresults.getString("methodid")); 

        MethodTrace.setMethod(method);
        MethodTrace.setRequirement(requirement);

        //checking whether the method is present in the superclasses


        MethodTrace.setGold(myresults.getString("goldfinal"));
        String reqMethod=MethodTrace.Requirement.ID+"-"+MethodTrace.Method.ID; 
        String reqClass=MethodTrace.Requirement.ID+"-"+MethodTrace.Method.Owner.ID;  

    //THIS IS THE LINE RESPONSIBLE FOR THE BUG  
MethodTrace.Method.Owner.DeveloperGold=classTraceHashMap.get(reqClass).DeveloperGold; 



         System.out.println(reqMethod+"-");

         methodtraceHashMap.put(reqMethod, MethodTrace);
     //         System.out.println("WE ARE IN THE LOOP "+methodtraceHashMap.get("1-1"));
    //          System.out.println("WE ARE IN THE LOOP "+methodtraceHashMap.get("1-1"));



    }

这是我的代码的简化版本,突出了我的错误的性质及其确切位置:

 for(MethodTrace MethodTrace: methodtraceHashMap2.values()) {
        String reqClass=MethodTrace.Requirement.ID+"-"+MethodTrace.Method.Owner.ID;  
        String reqMethod=MethodTrace.Requirement.ID+"-"+MethodTrace.Method.ID; 
//THIS IS THE LINE RESPONSIBLE FOR THE BUG           MethodTrace.Method.Owner.DeveloperGold=classTraceHashMap.get(reqClass).DeveloperGold; 

        methodtraceHashMap2.put(reqMethod, MethodTrace);
        System.out.println(methodtraceHashMap2.get("1-1").Method.Owner.getDeveloperGold());
    }

我正在通过从另一个哈希图中检索其值来设置哈希图中每个对象的值,如以下行所示

MethodTrace.Method.Owner.DeveloperGold=classTraceHashMap.get(reqClass).DeveloperGold; 

我在循环的第一次迭代中将methodtraceHashMap2.get("1-1").Method.Owner.getDeveloperGold()的值设置为"T",当我移到循环的第二次迭代时,我的循环为另一个键(键“ 2-1“):methodtraceHashMap2.get("2-1").Method.Owner.getDeveloperGold()"N",问题在于,在循环的第二次迭代中,methodtraceHashMap2.get("1-1").Method.Owner.getDeveloperGold()最终也被设置为"N" "T",因为它在第一次迭代中设置为"T"

这是我的其他课程

public final class MethodTrace {
    public static boolean modified = false;
    public Method Method= new Method();
    public Requirement Requirement=new Requirement();
    public String gold;
    public String prediction; 
    public String goldfinal;
    public String likelihood;
    public String why;
    boolean SubjectDeveloperEqualityFlag;
    public Methods<String> SuperClassesListMethodTraces;
    public Methods<String> InterfaceListMethodTraces;
    public Methods<String> ChildrenListMethodTraces;
    public Methods<String> ImplementationListMethodTraces;

    public boolean TraceSet; 
}

public class Method {
    public String ID; 
    public String methodname;
    public String fullmethodname;
    public Clazz Owner= new Clazz(); 
    public MethodList Callees= new MethodList(); 
    public MethodList Callers= new MethodList(); 
    public MethodList Interfaces= new MethodList(); 
    public MethodList Implementations= new MethodList(); 
    public MethodList Superclasses= new MethodList(); 
    public MethodList Children= new MethodList(); 
}

public class Clazz {

    public String ID; 
    public String classname;
    public String DeveloperGold=new String(); 
    public String SubjectGold; 
    public List<Clazz> Children= new ArrayList<Clazz>(); 
    public List<Clazz> Parents= new ArrayList<Clazz>();  
    public List<Clazz> Interfaces= new ArrayList<Clazz>();  
    public List<Clazz> Implementations= new ArrayList<Clazz>(); 
    public MethodList methods = new MethodList(); 
}

这是MethodTraceHashMap2的声明:

static LinkedHashMap<String, MethodTrace> methodtraceHashMap = new LinkedHashMap<String, MethodTrace>();

2 个答案:

答案 0 :(得分:0)

从您提到的行为来看,散列图中的对象似乎对于所有键都相同,即

Object firstObject = new Object();
for(.......){
firstObject.setDevloperGold("value");
methodtraceHashMap2.put("key",firstObject);
}

这就是为什么当您在第一个迭代中进行更改时,它会反映在过去的迭代中。相反,您应该这样做

for(.......){
Object firstObject = new Object();
firstObject.setDevloperGold("value");
methodtraceHashMap2.put("key",firstObject);
}

希望有帮助。

答案 1 :(得分:0)

您的循环具有以下逻辑

  • 对于methodtraceHashMap2的值中的每个MethodTrace
    • 从Requirement.ID和Owner.ID导出密钥
    • 使用该键从classTraceHashMap中获取一个值,并将MethodTrace中的DeveloperGold字段替换为该值
    • 从Requirement.ID和Method.ID派生另一个键
    • 使用第二个键将MethodTrace对象放入methodtraceHashMap2映射中

如果您要尝试查找DeveloperGold值并将其放在每个MethodTrace中,则不需要最后两个步骤。即只需执行以下操作即可。

  • 对于methodtraceHashMap2的值中的每个MethodTrace
    • 从Requirement.ID和Owner.ID导出密钥
    • 使用该键从classTraceHashMap中获取一个值,并将MethodTrace中的DeveloperGold字段替换为该值

如果另一方面,您正在地图中更改MethodTrace的键,而在该地图的值周围循环时,那是个坏主意。您应该将它们全部保存到新地图中。