Java LinkedHashMap:这两者有什么区别?
编辑:整个代码和数据库创建脚本可以从 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() 类似的键吗?为什么第二个版本可以工作而第一个版本不行?我花了一个小时调试这个问题,直到找到原因,但我仍然无法找出原因。
EDIT: The entire code and database creation script can be found from http://gitorious.org/scheator . The database script is in Schema/.
I have the following Java code:
A LinkedHashMap defined in an abstract class as
LinkedHashMap<Object, Data> list;
A descendant class that initializes this list like this:
list = new LinkedHashMap<Integer, Data>();
I add items like this:
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);
Now when I do this:
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());
Nothing is removed from the list, i.e. the first and last prints print the same size(). The key is also correct (I have verified there is an item by that id).
However, and this is my question, if I add the values like this:
Integer id = rs.getInt(FIELDS[0]);
String name = rs.getString(FIELDS[1]);
Data team = new Data(id, name);
list.put(id, team);
The code works! Shouldn't parseInt() produce a similar key to getInt()? Why does the second version work but the first doesn't? I spent a good hour debugging this until I found the reason and I still can't figure out the reason.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第一个例子:
第二个例子:
我不能肯定地说,因为我看不到代码的其余部分,但如果
key
变量在此调用中是一个整数:那么删除只会起作用如果使用 Integer 将对象放入映射中,这就是为什么它仅在调用
put
方法时 id 为整数时才起作用。字符串“123”不等于整数 123。另外,我假设您在第一个示例中错过了一行,但没有调用 list.put(id, team) 但这也可能是问题的根源
First example:
Second example:
I can't say for sure since I can't see the rest of the code, but if the
key
variable is an Integer in this call:then the remove will only work if the object was put into the map using an Integer and that is why it is only working when the id is integer when you call the
put
method. The String "123" does not equal the integer 123.Also I am assuming that you just missed a line in your first example but there was no call to list.put(id, team) but that could also be the source of your problems
应该没有区别,但是从您的示例中不清楚有很多事情:
deletedList
并不引用list
对象,自动装箱也可能使问题复杂化。将第二个示例中的
Integer id
替换为int id
,以将相同的参数传递给您的Data
构造函数。也许您可以发布完整的代码,以便我们可以准确地重现该场景?
更新
您正在使用字符串值作为原始代码中的键。然后,您的remove(key)方法中有一个对象键,所以我希望您此时将一个整数传递给该方法。字符串不会匹配整数作为键,这解释了为什么您的删除不起作用。
如果您使用泛型指定 HashMap(
LinkedHashMap
而不是),这种错误就不会发生 - 编译器会说类似
HashMap类型中的 put(Integer, Object) 方法;不适用于参数 (String, String)
There should be no difference, but there are a number of things that are not clear from your example:
deletedList
does not refer to thelist
objectAutoboxing may also be complicating the issue. Replace
Integer id
in the second sample withint id
to pass the same arguments to yourData
constructor.Maybe you could post up the complete code such that we can reproduce the scenario accurately?
Update
You are using String values as keys in your original code. You then have an Object key in your remove(key) method, so I expect you are passing an Integer to the method at this point. A String will not match an Integer as a key, which explains why your remove was not working.
If you use generics to specify your HashMap (
LinkedHashMap<Integer, Team>
instead of<Object, Team>
) this kind of error can't happen - the compiler will say something likeThe method put(Integer, Object) in the type HashMap<Integer,Object> is not applicable for the arguments (String, String)
亚纳蒙说得对。当您查看差异时,情况非常清楚:
请注意,在原始版本中, int(自动装箱为 Integer)被传递到 Data 构造函数中。但正在放入的 id 仍然是一个字符串。
Yanamon is right. It's pretty clear when you look at the diff:
Note that in the original version, an int (auto-boxed to Integer) is being passed into the Data constructor. But id, which is being putted, is still a String.
我的猜测是,在第二种情况下,您将其显式转换为 Integer
int
,而在第一种情况下,它仍然是来自 parseInt 的 javadoc 的
My guess is that int the second case you cast it explicitly into an Integer
while on the first case it remains an int
from the javadoc of parseInt
如果我是你,我会使用调试器在放置之前和之后以及删除之前和之后检查 LinkedHashMap 的内容。进入
remove()
方法(源代码是 JDK 的一部分),看看它在做什么。您的代码很可能没有正确添加或删除对象。这里很难看到,因为代码示例不完整。至于 rs.getInt() 和 Integer.parseInt() ,第一个是数据库供应商特定的(我假设 rs 是一个 ResultSet ) ,因此它们可能不会有相同的行为。但是,一旦创建了 Integer 键(您可以使用调试器验证这一点),它对于 HashMap 或 LinkedHashMap 的目的应该是等效的。但是您的代码示例使事情变得更加复杂;您正在使用
rs.getString()
,然后使用Integer.parseInt()
。虽然如果发生这种情况我会感到惊讶,但数据库驱动程序可能会将 id 列格式化为一个令parseInt()
感到困惑的字符串。对我来说,只执行 rs.getInt() 更具可读性。If I were you I would inspect the contents of the LinkedHashMap using a debugger, before and after your put and before and after your remove. Step into the
remove()
method (the source code is part of the JDK) and see what it is doing. Odds are your code is not adding or removing the object correctly. It's hard to see here because the code sample is incomplete.As for
rs.getInt()
andInteger.parseInt()
, the first is database-vendor specific (I assume rs is aResultSet
), and thus they may not have the same behaviour. However, once the Integer key is created (you can verify this with your debugger) it should be equivalent for HashMap or LinkedHashMap purposes. But your code sample complicates things further; you are usingrs.getString()
and thenInteger.parseInt()
. While I would be surprised if this happened, it's possible that the database driver is formatting the id column into a string that confusesparseInt()
. To me it's far more readable to just dors.getInt()
.