编辑:可以从http://gitorious.org/scheator找到整个代码和数据库创建脚本。数据库脚本位于Schema /.
中我有以下Java代码:
在抽象类中定义为
的LinkedHashMapLinkedHashMap<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()的键吗?为什么第二个版本有效,但第一个版本没有?我花了一个小时调试这个,直到找到原因,我仍然无法弄清楚原因。
答案 0 :(得分:2)
应该没有区别,但是有很多事情从你的例子中不清楚:
deletedList
未引用list
对象自动装箱也可能使问题复杂化。将第二个示例中的Integer id
替换为int id
,将相同的参数传递给Data
构造函数。
也许您可以发布完整的代码,以便我们可以准确地重现场景?
更新
您在原始代码中使用字符串值作为键。然后在remove(key)方法中有一个Object键,所以我希望你现在将Integer传递给方法。 String不会将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)
答案 1 :(得分:2)
第一个例子:
String id = rs.getString(FIELDS[0]);
第二个例子:
Integer id = rs.getInt(FIELDS[0]);
我不能肯定地说,因为我看不到剩下的代码,但是如果key
变量是这个调用中的整数:
obj = (Data)list.remove(key);
然后删除只有在使用Integer将对象放入地图时才有效,这就是为什么只有在调用put
方法时id为整数时它才起作用。字符串“123”不等于整数123。
另外我假设您在第一个示例中错过了一行,但没有调用list.put(id,team),但这也可能是您问题的根源
答案 2 :(得分:1)
Yanamon是对的。当你看the 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(自动装箱为Integer)正在传递给Data构造函数。但正在推出的id仍然是一个字符串。
答案 3 :(得分:0)
我的猜测是,在第二种情况下,你将它明确地转换为整数
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.
答案 4 :(得分:0)
如果我是你,我将使用调试器检查LinkedHashMap的内容,在put之前和之后以及删除之前和之后。进入remove()
方法(源代码是JDK的一部分),看看它在做什么。赔率是您的代码没有正确添加或删除对象。这里很难看到,因为代码示例不完整。
至于rs.getInt()
和Integer.parseInt()
,第一个是特定于数据库供应商(我假设rs是ResultSet
),因此它们可能没有相同的行为。但是,一旦创建了Integer键(您可以使用调试器验证它),它应该等同于HashMap或LinkedHashMap目的。但是你的代码示例使事情进一步复杂化;您使用的是rs.getString()
,然后是Integer.parseInt()
。虽然如果发生这种情况我会感到惊讶,但数据库驱动程序可能会将id列格式化为混淆parseInt()
的字符串。对我而言,只需rs.getInt()
就可以了。