Java哈希表在';把';
我正在尝试使用Eclipse向Java中的哈希表添加条目。在put操作期间,只有一个键被新键和值覆盖。哈希表的计数被正确维护,但是(键,值)对中的一个丢失 以下是我的示例代码:Java哈希表在';把';,java,hashtable,Java,Hashtable,我正在尝试使用Eclipse向Java中的哈希表添加条目。在put操作期间,只有一个键被新键和值覆盖。哈希表的计数被正确维护,但是(键,值)对中的一个丢失 以下是我的示例代码: ArrayList<Double> list; Hashtable<Val,ArrayList<Double>> numbers = new Hashtable<Val,ArrayList<Double>>(); while((line = brMyHashv
ArrayList<Double> list;
Hashtable<Val,ArrayList<Double>> numbers = new Hashtable<Val,ArrayList<Double>>();
while((line = brMyHashval.readLine()) != null)
{
if(!(line.isEmpty()))
{
String[] temp;
temp = line.split(" ");
eDouble = Double.parseDouble(temp[2].toString());
Val key = new Val(Double.parseDouble(temp[0].toString()) ,Double.parseDouble(temp[1].toString()) );
if(!(numbers.containsKey(key)))
{
list = new ArrayList<Double>();
numbers.put(key, list);
}
else
{
list = numbers.get(key);
}
list.add(eDouble);
}
}
为什么钥匙会在那个特定的时刻被删除
[编辑]hashcode和equals:我使用eclipse自动导入这些方法
//(x,y)是(a,b)
}确保哈希和相等值满足其要求
每个实例都应该有一个唯一的散列,如果它们仅相等,那么equals应该为true。误报意味着误报值映射到同一个键 上面的Sumindra意味着,如果要使用自定义类作为映射中的键,则必须按照指定编写equals()和hashCode()方法。执行以下操作(例如:
public boolean equals(K other) {
return a == other.a && b == other.b;
}
public int hashCode() {
return new Double(a).hashCode() ^ new Double(b).hashCode();
}
这保证:
- 如果两个K对象具有相同的成员,则它们将重新相等
- 如果两个K对象具有相同的成员,则它们具有相同的哈希代码
这是映射关键对象的一个要求。我无法重现您的问题,这正是我正在运行的代码(没有简化为其他答案,以便尽可能接近您的原始问题) 这不是你所期望的吗
其他答案在简化hashCode和equals方面有很多优点。此外,您不需要对已经是字符串的对象执行toString()。问题在于您正在使用调试器检查HashMap的内容 我假设键(1,2)和(7,8)都保存在用于保存键的哈希表的同一个插槽中。添加(7,8)时,(1,2)移动到(7,8)的“后面”-您必须检查(7,8)项的
下一个项
在代码末尾添加以下内容以查看HashMap中的实际内容:
for (Val key : numbers.keySet()) {
System.out.printf("%.1f %.1f: %s%n", key.x, key.y, numbers.get(key));
}
hashCode和equals做什么?什么是“Val”类?它与“K”相同吗是的。对不起。Val类是KI类不能复制的,它按照你描述的方式工作。你希望它在这里工作,所有的键都创建一次。你能发布一个SSCCE吗?你同时使用K类和Val类,我不认为你运行的代码是你显示的代码。问题不在于调试器,而是数据如何存储在HashMap中-请参阅我的答案即使使用t你提到的代码,同样的问题也会发生。例如,两个K对象对于不同的成员返回相同的值。我应该以不同的方式编写方法吗?我找不到任何理由,为什么即使在使用^@SyncMaster时,它也会为不同的成员提供相同的值。请注意,两个对象可以返回相同的hashCode
,但仍然是不同的le字符串的位可能比哈希代码多得多,因此不可能为每个字符串生成唯一的代码。在您的情况下,两个双精度字符串的位可能比long(哈希代码返回类型)多@CarlosHeuberger:所以更好的处理这种情况的方法是编写我自己合适的哈希代码?@SyncMaster-没有必要,在大多数情况下也没有办法拥有唯一的哈希代码。在您的情况下,如果密钥由2个双精度定义,即2乘以64位,那么您至少需要128位才能拥有唯一的哈希代码。在Java中,哈希代码是o只有32位的long,无法唯一表示128位!使用调试器检查HashMap可能不直观,这是一个很好的发现。
public boolean equals(K other) {
return a == other.a && b == other.b;
}
public int hashCode() {
return new Double(a).hashCode() ^ new Double(b).hashCode();
}
public class HashProblem {
public static class Val {
private double x;
private double y;
public Val(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Val other = (Val) obj;
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
return false;
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
return false;
return true;
}
}
public static void main(String... args) throws Exception {
ArrayList<Double> list;
String line;
BufferedReader brMyHashval = new BufferedReader(new InputStreamReader(new FileInputStream("HashProblem.txt")));
Hashtable<Val, ArrayList<Double>> numbers = new Hashtable<Val, ArrayList<Double>>();
while ((line = brMyHashval.readLine()) != null) {
if (!(line.isEmpty())) {
String[] temp;
temp = line.split(" ");
Double eDouble = Double.parseDouble(temp[2].toString());
Val key = new Val(Double.parseDouble(temp[0].toString()), Double.parseDouble(temp[1].toString()));
if (!(numbers.containsKey(key))) {
list = new ArrayList<Double>();
numbers.put(key, list);
System.err.println("Created " + key.x + " " + key.y);
} else {
list = numbers.get(key);
}
list.add(eDouble);
System.err.println("Inserted into " + key.x + " " + key.y + " value " + eDouble + " size " + list.size() + " " + list);
}
}
}
Created 1.0 2.0
Inserted into 1.0 2.0 value 9.0 size 1 [9.0]
Created 3.0 4.0
Inserted into 3.0 4.0 value 9.0 size 1 [9.0]
Created 5.0 6.0
Inserted into 5.0 6.0 value 9.0 size 1 [9.0]
Inserted into 1.0 2.0 value 8.0 size 2 [9.0, 8.0]
Inserted into 5.0 6.0 value 8.0 size 2 [9.0, 8.0]
Inserted into 1.0 2.0 value 7.0 size 3 [9.0, 8.0, 7.0]
Created 7.0 8.0
Inserted into 7.0 8.0 value 7.0 size 1 [7.0]
Inserted into 3.0 4.0 value 7.0 size 2 [9.0, 7.0]
Inserted into 5.0 6.0 value 10.0 size 3 [9.0, 8.0, 10.0]
Inserted into 1.0 2.0 value 10.0 size 4 [9.0, 8.0, 7.0, 10.0]
Created 1.0 3.0
Inserted into 1.0 3.0 value 10.0 size 1 [10.0]
Created 1.0 4.0
Inserted into 1.0 4.0 value 10.0 size 1 [10.0]
for (Val key : numbers.keySet()) {
System.out.printf("%.1f %.1f: %s%n", key.x, key.y, numbers.get(key));
}