4

編集: コード全体とデータベース作成スクリプトはhttp://gitorious.org/scheatorにあります。データベース スクリプトは Schema/ にあります。

次の Java コードがあります。

抽象クラスで次のように定義された LinkedHashMap

LinkedHashMap<Object, Data> list;

このリストを次のように初期化する子孫クラス:

list = new LinkedHashMap<Integer, Data>();

次のような項目を追加します。

    String id = rs.getString(FIELDS[0]);
    String name = rs.getString(FIELDS[1]);
    Data team = new Data(Integer.parseInt(id.trim()), name);
    list.put(id, team);

今私がこれを行うとき:

    System.err.println("delete() count: " + list.size());

    System.err.println("delete() key value " + key);
    Data obj;
    obj = (Data)list.remove(key);
    deletedList.put(key, obj);
    System.err.println("delete() count: " + list.size());

リストからは何も削除されません。つまり、最初と最後の印刷は同じサイズで印刷されます()。キーも正しいです (その ID のアイテムがあることを確認しました)。

ただし、次のような値を追加すると、これが私の質問です。

    Integer id = rs.getInt(FIELDS[0]);
    String name = rs.getString(FIELDS[1]);
    Data team = new Data(id, name);
    list.put(id, team);

コードが機能します!parseInt() は getInt() と同様のキーを生成するべきではありませんか? 2 番目のバージョンは機能するのに、最初のバージョンは機能しないのはなぜですか? 理由がわかるまで、これをデバッグするのにかなりの時間を費やしましたが、それでも理由がわかりません。

4

5 に答える 5

2

違いはないはずですが、あなたの例からは明らかでないことがいくつかあります。

  • deletedListlistオブジェクトを参照していません
  • 使用されているデータベース内のレコードはどちらの場合も同じです (おそらく、最初の例では、既にマップにある別の int が使用されています)

オートボクシングも問題を複雑にしている可能性があります。Integer id2 番目のサンプルをに置き換えてint id、同じ引数をDataコンストラクターに渡します。

シナリオを正確に再現できるように、完全なコードを投稿していただけませんか?


アップデート

元のコードで文字列値をキーとして使用しています。次に、remove(key) メソッドに Object キーがあるので、この時点でメソッドに Integer を渡していると思います。文字列はキーとして整数と一致しないため、削除が機能しなかった理由が説明されています。

ジェネリックを使用して HashMap を指定する場合 (LinkedHashMap<Integer, Team>の代わりに<Object, Team>)、この種のエラーは発生しません - コンパイラは次のようなことを言います

The method put(Integer, Object) in the type HashMap<Integer,Object> is not applicable for the arguments (String, String)

于 2010-03-01T19:19:21.327 に答える
2

最初の例:

String id = rs.getString(FIELDS[0]);

2 番目の例:

Integer id = rs.getInt(FIELDS[0]);

コードの残りの部分が見えないので、はっきりとは言えませんがkey、この呼び出しで変数が Integer の場合:

obj = (Data)list.remove(key);

put削除は、オブジェクトが整数を使用してマップに配置された場合にのみ機能します。そのため、メソッドを呼び出すときに id が整数の場合にのみ機能します。文字列「123」は整数の 123 と等しくありません。

また、最初の例で行を見逃しただけで、list.put(id, team) への呼び出しがなかったと仮定していますが、それが問題の原因である可能性もあります

于 2010-03-01T19:29:10.017 に答える
1

やなもん そうです。diffを見るとかなり明確です:

             while (rs.next()) {
-                String id = rs.getString(FIELDS[0]);
+                Integer id = rs.getInt(FIELDS[0]);
                 String name = rs.getString(FIELDS[1]);
-                Data team = new Data(Integer.parseInt(id.trim()), name);
+                Data team = new Data(id, name);
                 list.put(id, team);

元のバージョンでは、int (整数に自動ボックス化) が Data コンストラクターに渡されていることに注意してください。しかし、挿入されている id はまだ文字列です。

于 2010-03-01T19:35:10.543 に答える
0

私の推測では、整数に明示的にキャストする 2 番目のケースは int です。

Integer id = rs.getInt(FIELDS[0]);

最初のケースでは int のままです

Integer.parseInt(id.trim())

parseInt の javadoc から

static int  parseInt(String s) 
Parses the string argument as a signed decimal integer.
于 2010-03-01T19:14:31.680 に答える
0

私があなただったら、デバッガーを使用して、配置の前後と削除の前後に LinkedHashMap の内容を調べます。メソッドにステップ インしremove()(ソース コードは JDK の一部です)、メソッドが何を行っているかを確認します。コードがオブジェクトを正しく追加または削除していない可能性があります。コード サンプルが不完全なため、ここではわかりにくいです。

rs.getInt()とに関してInteger.parseInt()は、1 つ目はデータベース ベンダー固有のものであり (rs は であると仮定しますResultSet)、したがって、それらは同じ動作をしない可能性があります。ただし、Integer キーが作成されると (デバッガーでこれを確認できます)、HashMap または LinkedHashMap の目的で同等になるはずです。しかし、あなたのコード サンプルは事態をさらに複雑にします。あなたが使用しているしrs.getString()、その後Integer.parseInt()。これが起こったら驚かれることでしょうが、データベース ドライバーが id 列を混乱させる文字列にフォーマットしている可能性がありますparseInt()。私にとっては、単に実行する方がはるかに読みやすいですrs.getInt()

于 2010-03-01T19:23:58.907 に答える