【问题标题】:HashMap Value which is an object has an attribute overridden with incorrect value作为对象的 HashMap 值具有被错误值覆盖的属性
【发布时间】:2018-12-21 08:32:43
【问题描述】:

我正在迭代一个以对象为值,以字符串为键的哈希图。

 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>();

【问题讨论】:

  • 如果您使用以小写字符开头的名称作为变量,这将不那么令人困惑。我假设MethodOwnerDeveloperGold 是公共字段,对吗?也许其中任何一个被意外声明为static
  • 我同意@Hulk。我假设 Requirement 和 ID 没有定义为静态的。也许也发布这些课程。方法traceHashMap2.put() 不是必需的。您没有在地图中放置另一个 MethodTrace 实例,您只需修改一个属性或它。
  • 刚刚添加了它们
  • 在迭代时更改集合通常是个坏主意。

标签: java hashmap


【解决方案1】:

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

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

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

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

希望对你有帮助。

【讨论】:

  • 我已经在循环内部而不是外部创建了我的对象,所以你的建议不起作用
  • 您能分享您在哪里为methodtraceHashMap2 Map 添加值吗?
  • 刚刚在帖子顶部添加了我的原始代码
【解决方案2】:

您的循环具有以下逻辑

  • 对于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 的键,而您正在循环该映射的值,那么这是一个坏主意。您应该将它们全部保存到新地图中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多