考虑以下HashMap<String,String> hashMap=new HashMap<>();
hashMap.put(new String("ABC"), "Hello");
hashMap.put("ABC", "Hello");
System.out.println(hashMap.size());
实施
size
代码如何将StringBuffer
作为1进行评估?但是,如果我使用String
代替Category
代码,则返回值为2。
这背后的原因是什么?
答案 0 :(得分:6)
HashMap
使用hashCode
方法确定存储桶,然后使用equals
来确定是否有任何现有对象与要添加的对象相同。在您的情况下,"ABC"
和new String("ABC")
将具有相同的hashCode
,并且String.equals
将被视为相等。因此这两个对象将被视为相同。
如果您不想这样,那么您可以考虑使用IdentityHashMap使用对象引用来比较相等。
答案 1 :(得分:3)
HashMap使用Object.equals(other)
作为2个对象是否应计为&#34;相同&#34;的最终仲裁者。使用String,equals
可以有效地比较字符串的字符内容,因此"ABC".equals(new String("ABC"));
将返回true
。
StringBuffer使用对象的equals
默认实现,它基本上检查两个对象是引用相同的(即它们都指向了确切的相同的内存地址 - 这是==
为java中的对象所做的事情。使用两个不同的new
语句构造的两个StringBuffers永远不会是引用相同的,因此永远不会是equal
。这有很好的理由:大部分时间,我们希望对象的equals
方法为给定的参数返回相同的答案,无论它何时被调用。由于StringBuffer的内容可以被操作,因此两个缓冲区在一个时间点可能具有相同的内容,但是随后在其中一个缓冲区被附加到后面时具有不同的内容。
StringBuffer可变的事实可能使它成为用作地图键的不良候选者。除非您拥有与原始put
完全相同的 StringBuffer,否则您将无法在地图上执行查找。相反,如果由于某种原因这种行为是你想要的,你可以使用IdentityHashMap,它将始终使用对象的内存地址来确定它是否相等到另一个,不管它的类型。注意使用带有字符串键的IdentityHashMap - 由于string interning,在代码中不同位置构造的2个等效字符串(来自文字)实际上指向同一块内存,因此参考相同。
答案 2 :(得分:0)
import matplotlib.pyplot as plt
a=((open('A.txt').read()).lower()).split()
c=((open('C.txt').read()).lower()).split()
f=((open('F.txt').read()).lower()).split()
documents=[a,f,c]
import math
names=[...] #important words
for a in names:
for b in names:
count = 0
for x in documents:
if a != b:
if a in x and b in x:
count += 1
else:
n = x.count(a)
if n >= 2:
count += math.factorial(n)/math.factorial(n - 2)/2
print('{} x {} = {}'.format(a, b, count))
中缺少类型。如果您想创建HashMap<String,String> hashMap=new HashMap<>();
的地图,那么您将无法创建String, String
个对象作为关键字。如果您想同时支持两者,则可以使用StringBuilder
代替Object
作为密钥。
如果您想支持String
和String
,那么您的代码将是
StringBuilder
以下是尺寸差异的解释。
&#34;任何价值&#34;被视为HashMap<Object,String> hashMap=new HashMap<Object, String>();
类的实例。 String
与StringBuilder
不同。在您的代码中,同一个类的对象被创建为键,这会产生相同的hashCode(请参阅String
中的hashCode()
函数)。但是,String.java
使用了Object.java中的StringBuilder
。因此,他们有不同的hashCode,并进行相应的处理。
答案 3 :(得分:0)
HashMap的put(K key,V value)方法首先通过key.hashCode()%m散列到存储桶,然后遍历单个链接的Map.Entry对象列表以识别它 密钥通过key.equals(k)存在。如果找到一个键,它会更新该条目的值,否则它会将该键插入链表的前面
1)对于StringBuffer案例
(i) new StringBuffer("ABC").equals(new StringBuffer("ABC")) is false
(ii) new StringBuffer("ABC")!=new StringBuffer("ABC").hashCode() is false
这是因为StringBuffer不会覆盖并使用Objects equals(Object o)和hashCode()。 所以它们是地图中的两个不同的条目
2)对于字符串大小写
(i) "ABC".equals(new String("ABC")) is true
(ii) "ABC".hashCode()==new String("ABC").hashCode() is true
所以这两个是地图中的单个条目
答案 4 :(得分:0)
我认为你需要了解什么是hashmap, 等号和哈希码用于存储和检索分配的内存位置中的对象。 因此,在您的情况下,使用内容而不是keyObjects引用验证密钥,因为它是String。即使你创建String =“ABC”文字或新字符串(“ABC”); 在这种情况下,Equals方法结果为true,因此将现有密钥替换为新密钥。它是SET的基本概念。 HashMap使用SET作为键。因此,当我们尝试添加匹配的新密钥时,将使用equals方法替换现有密钥。 出于这个原因,我们应该正确地覆盖equals和hashcode方法。 规则: 如果两个对象相等,则它们必须具有相同的哈希码。 如果两个对象具有相同的哈希码,则它们可能相等也可能不相等。