0

我问了一个关于在多个独立 hashMap 对象中搜索特定键的先前问题,关于如何实现这一点,或者我是否应该为我的键实现一个特定的新类。

最终,在进一步阅读文档后,注意到 HashMap 确实已经实现了 equals() 和 hashcode() 方法,我决定最好在代码中使用 HashMap 作为键。

我来测试了,我已经构建了以下类型的对象 HashMap< HashMap, Object> 它实际上是从数据库中的信息构建的。

对象本身包含一个 HashMap 类型的成员

所以我遍历我的 Object 成员,并打印结果......

for (HashMap<String, String> keVal: Object.getMember().keySet())
    {
        System.out.println("the key of: " + keVal.toString() +"has a hash code of " + keVal.hashCode() +
                "here is the data for this key:\n" +
                Object.getMember().get(keVal).getColData().toString() );

    }

您会注意到,我已打印出 keVal 有关内容及其哈希码的信息,为了更好地衡量,然后在下一行中,我打印出与指定 keVal 信息相关的成员中的信息。然而,问题是我总是从我的地图中得到同一行信息的返回。

这是输出的一小段

the key of: {OBS=002018}has a hash code of 1420118533 here is the data for this key:
{OBS=002035, CHIMIO1=null, CHIMIO2=null, DTHEMO=2011-11-09 00:00:00, PNN=7.4, ATCDND=0, HEMA=4.21, ALAT=23.0, LYMP=1.6, CHIMIOT1=0, CHIMIOT2=0, PNE=0.1, PNB=0.0, TAILLE=168, NBCY1=null, RXANT=0, NBCY2=null, CHIMIOX2=null, CONTRAC=1, CHIMIOX1=null, DTFCHIMIO1=null, DTFCHIMIO2=null, ASAT=21.0, ECRIT11=0, ECRIT10=0, SCORPO=1.81, MONO=0.5, HEMATO=38.2, CHIMIOANT=0, ID_VISIT=0, DTDCHIMIO2=null, DTDCHIMIO1=null, ECRIT25=0, ECRIT24=0, ECRIT23=0, LEUCO=9.6, ECRIT7=0, ECRIT8=0, ECRIT9=0, HB=13.2, ECRIT20=0, ECRIT21=0, ECRIT22=0, ECRIT1=0, ICRIT1=1, ECRIT2=0, ECRIT3=0, ECRIT4=0, ECRIT5=0, ECRIT6=0, PLQ=214.0, MENO=0, DTBIOCH=2011-11-09 00:00:00, ECRIT13=0, ECRIT12=0, ECRIT15=0, ECRIT14=0, ECRIT17=0, ECRIT16=0, ECRIT19=0, ECRIT18=0}
the key of: {OBS=002017}has a hash code of 1420118532 here is the data for this key:
{OBS=002035, CHIMIO1=null, CHIMIO2=null, DTHEMO=2011-11-09 00:00:00, PNN=7.4, ATCDND=0, HEMA=4.21, ALAT=23.0, LYMP=1.6, CHIMIOT1=0, CHIMIOT2=0, PNE=0.1, PNB=0.0, TAILLE=168, NBCY1=null, RXANT=0, NBCY2=null, CHIMIOX2=null, CONTRAC=1, CHIMIOX1=null, DTFCHIMIO1=null, DTFCHIMIO2=null, ASAT=21.0, ECRIT11=0, ECRIT10=0, SCORPO=1.81, MONO=0.5, HEMATO=38.2, CHIMIOANT=0, ID_VISIT=0, DTDCHIMIO2=null, DTDCHIMIO1=null, ECRIT25=0, ECRIT24=0, ECRIT23=0, LEUCO=9.6, ECRIT7=0, ECRIT8=0, ECRIT9=0, HB=13.2, ECRIT20=0, ECRIT21=0, ECRIT22=0, ECRIT1=0, ICRIT1=1, ECRIT2=0, ECRIT3=0, ECRIT4=0, ECRIT5=0, ECRIT6=0, PLQ=214.0, MENO=0, DTBIOCH=2011-11-09 00:00:00, ECRIT13=0, ECRIT12=0, ECRIT15=0, ECRIT14=0, ECRIT17=0, ECRIT16=0, ECRIT19=0, ECRIT18=0}
the key of: {OBS=002019}has a hash code of 1420118534 here is the data for this key:
{OBS=002035, CHIMIO1=null, CHIMIO2=null, DTHEMO=2011-11-09 00:00:00, PNN=7.4, ATCDND=0, HEMA=4.21, ALAT=23.0, LYMP=1.6, CHIMIOT1=0, CHIMIOT2=0, PNE=0.1, PNB=0.0, TAILLE=168, NBCY1=null, RXANT=0, NBCY2=null, CHIMIOX2=null, CONTRAC=1, CHIMIOX1=null, DTFCHIMIO1=null, DTFCHIMIO2=null, ASAT=21.0, ECRIT11=0, ECRIT10=0, SCORPO=1.81, MONO=0.5, HEMATO=38.2, CHIMIOANT=0, ID_VISIT=0, DTDCHIMIO2=null, DTDCHIMIO1=null, ECRIT25=0, ECRIT24=0, ECRIT23=0, LEUCO=9.6, ECRIT7=0, ECRIT8=0, ECRIT9=0, HB=13.2, ECRIT20=0, ECRIT21=0, ECRIT22=0, ECRIT1=0, ICRIT1=1, ECRIT2=0, ECRIT3=0, ECRIT4=0, ECRIT5=0, ECRIT6=0, PLQ=214.0, MENO=0, DTBIOCH=2011-11-09 00:00:00, ECRIT13=0, ECRIT12=0, ECRIT15=0, ECRIT14=0, ECRIT17=0, ECRIT16=0, ECRIT19=0, ECRIT18=0}
the key of: {OBS=002014}has a hash code of 1420118529 here is the data for this key:
{OBS=002035, CHIMIO1=null, CHIMIO2=null, DTHEMO=2011-11-09 00:00:00, PNN=7.4, ATCDND=0, HEMA=4.21, ALAT=23.0, LYMP=1.6, CHIMIOT1=0, CHIMIOT2=0, PNE=0.1, PNB=0.0, TAILLE=168, NBCY1=null, RXANT=0, NBCY2=null, CHIMIOX2=null, CONTRAC=1, CHIMIOX1=null, DTFCHIMIO1=null, DTFCHIMIO2=null, ASAT=21.0, ECRIT11=0, ECRIT10=0, SCORPO=1.81, MONO=0.5, HEMATO=38.2, CHIMIOANT=0, ID_VISIT=0, DTDCHIMIO2=null, DTDCHIMIO1=null, ECRIT25=0, ECRIT24=0, ECRIT23=0, LEUCO=9.6, ECRIT7=0, ECRIT8=0, ECRIT9=0, HB=13.2, ECRIT20=0, ECRIT21=0, ECRIT22=0, ECRIT1=0, ICRIT1=1, ECRIT2=0, ECRIT3=0, ECRIT4=0, ECRIT5=0, ECRIT6=0, PLQ=214.0, MENO=0, DTBIOCH=2011-11-09 00:00:00, ECRIT13=0, ECRIT12=0, ECRIT15=0, ECRIT14=0, ECRIT17=0, ECRIT16=0, ECRIT19=0, ECRIT18=0}
the key of: {OBS=002013}has a hash code of 1420118528 here is the data for this key:
{OBS=002035, CHIMIO1=null, CHIMIO2=null, DTHEMO=2011-11-09 00:00:00, PNN=7.4, ATCDND=0, HEMA=4.21, ALAT=23.0, LYMP=1.6, CHIMIOT1=0, CHIMIOT2=0, PNE=0.1, PNB=0.0, TAILLE=168, NBCY1=null, RXANT=0, NBCY2=null, CHIMIOX2=null, CONTRAC=1, CHIMIOX1=null, DTFCHIMIO1=null, DTFCHIMIO2=null, ASAT=21.0, ECRIT11=0, ECRIT10=0, SCORPO=1.81, MONO=0.5, HEMATO=38.2, CHIMIOANT=0, ID_VISIT=0, DTDCHIMIO2=null, DTDCHIMIO1=null, ECRIT25=0, ECRIT24=0, ECRIT23=0, LEUCO=9.6, ECRIT7=0, ECRIT8=0, ECRIT9=0, HB=13.2, ECRIT20=0, ECRIT21=0, ECRIT22=0, ECRIT1=0, ICRIT1=1, ECRIT2=0, ECRIT3=0, ECRIT4=0, ECRIT5=0, ECRIT6=0, PLQ=214.0, MENO=0, DTBIOCH=2011-11-09 00:00:00, ECRIT13=0, ECRIT12=0, ECRIT15=0, ECRIT14=0, ECRIT17=0, ECRIT16=0, ECRIT19=0, ECRIT18=0}

如您所见,检索到的值始终与 OBS=002035 相关,有趣的是,这是映射中的最后一个值(如果我通过检索成员数组对其进行迭代)但在上面的打印输出中没有?需要注意的是,无论我运行多少次代码,我总是会得到一个 OBS=002035 的副本作为我为指定键返回的值!

我有点迷茫,这是HashMap ^中的错误吗?或者我如何检索 keVal 成员的问题。还是 for 循环的第一行实际上是一个潜在的 classCastException,我需要以某种方式处理?

如果我实现我自己的个人 keyObject,然后有一个 HashMap 成员,并且针对 HashMap 成员中的值实现 equals() 和 hashCode(),我还会遇到同样的问题吗?(这可能是一个有趣的问题,因为我将要如何做这件事并测试结果)。

编辑1:我可能在其他地方使用了我的代码,请参阅下面我对 Louis 的回复。一旦我确认这是问题所在,我会要求模组删除这个问题,因为这是一个“愚蠢的程序员”问题,而不是真正的问题!

4

1 回答 1

0

好的,我发现了问题...

在阅读我要发布的代码并添加一些额外的评论时,我发现了问题和解决方案。

程序流程如下:

在结果集上使用“select * from [tableName]”循环获取数据,将每一行放入一个临时对象中。

问题方案

在发出 while(resultSet.next()) 循环之前,我创建了临时对象来保存数据。在这个循环中,我将信息添加到上述临时对象中。

在移动到结果集中的下一行之前(即下一个 while 迭代),我将临时对象传递到其他地方。

然而,虽然在首次亮相时临时对象中的信息报告是正确的,但使用它的过程似乎使用的是原始版本而不是与当前循环的当前迭代相关的版本?

将我的临时对象的创建移动到我的 while 循环内部解决了这个问题。这是伪代码...

//bad code
ResultSet rs =  getDataFromDBMS("Select * from [tableName];");

Object temp = new objectToHoldInfoFromResultSet();

//loop over the result set
while (rs.next)//for each row in the result set
        {
        for(int i=1; i<=rs.getNumberColums; i++)
                {
                temp.add(infoAboutColumn);
                }
        temp.printInfo();//prints correct info
        anotherObject(makeUseOf(temp));//use info from first iteration.


        }

//Seemingly each loop into the while the temp.doSomethingToData(); uses the temp object created in the first iteration

//good code
ResultSet rs =  getDataFromDBMS("Select * from [tableName];");


//loop over the result set
while (rs.next)//for each row in the result set
        {
         Object temp = new objectToHoldInfoFromResultSet();//moving declaration of temp into the while loop solves the problem.
        for(int i=1; i<=rs.getNumberColums; i++)
                {
                temp.add(infoAboutColumn);
                }
        temp.printInfo();//prints current info

        anotherObject(makeUseOf(temp));//uses the current info.


        }

因此,虽然上述解决了问题,但它引发了另一个问题。

temp.printInfo(); call 始终打印在 while 循环中获得的正确“当前”信息。anotherObject(makeUseOf(temp) 但是从 while 循环外部调用 temp 对象(如果那是我创建它的地方) - 即它似乎没有引用与 temp.printInfo() 调用相同的 temp 对象.

我会在另一个问题中提出这个问题,并输入一个链接......这是新问题

于 2012-06-28T10:12:19.600 回答