0

これを実装する方法、またはキーに特定の新しいクラスを実装する必要があるかどうかについて、複数の独立した hashMap オブジェクトで特定のキーを検索するSO に関する以前の質問をしました。

最終的に、ドキュメントをさらに読み、HashMap がすでに equals() および hashcode() メソッドを実装していることに気付いた後、コードのキーとして HashMap を使用することをお勧めします。

私はテストに来て、次のタイプのオブジェクトを構築しました HashMap< HashMap, Object> 実際には、データベースの情報から構築されています。

オブジェクト自体に HashMap 型のメンバーが含まれている

オブジェクトメンバーをループして、結果を出力します...

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() を実装すると、同じ問題が発生しますか? (私はこれをどのように実行し、結果をテストしようとしているので、それは少し危険な質問かもしれません)。

edit1: 私は自分のコードを他の場所で roger した可能性があります。以下の Louis への私の応答を参照してください。これが問題の場所であることを確認したら、本当の問題ではなく、「ドピープログラマー」の問題として、モッドに質問を削除するように依頼します。

4

1 に答える 1

0

OK、問題が見つかりました...

投稿しようとしていたコードを読み、いくつかのコメントを追加しているうちに、問題と解決策が見つかりました。

プログラムの流れは次のとおりでした。

結果セットに対して「select * from [tableName]」ループでデータを取得し、各行を一時オブジェクトに入れます。

問題解決

while(resultSet.next()) ループを発行する前に、データを保持する一時オブジェクトを作成しました。このループ内で、上記の一時オブジェクトに情報を追加しました。

resultSet の次の行 (次の while 反復) に移動する前に、一時オブジェクトを別の場所に渡しました。

しかし、デビュー時の一時オブジェクトの情報の報告は正しかったが、それを使用するプロセスは、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.printInfo() 呼び出しと同じ一時オブジェクトを参照していないようです.

別の質問でこれを質問し、リンクを追加します...ここに新しい質問があります

于 2012-06-28T10:12:19.600 に答える