为什么我能够将Map中的重复包含作为键, 我对地图很感兴趣:它包含重复的密钥
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileExample1 {
private static final String FILENAME = "E:\\test\\filename.txt";
public static void main(String[] args) {
BufferedReader br = null;
FileReader fr = null;
try {
//br = new BufferedReader(new FileReader(FILENAME));
fr = new FileReader(FILENAME);
br = new BufferedReader(fr);
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
if (fr != null) fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
但是在这个例子中,我能够在LinkedHashMap和HashMap中保留重复的键
答案 0 :(得分:1)
你说得对,Map
没有重复键(这只适用于键,值可以相等)。如果在已添加的键下放置一个值,则将覆盖先前的值。因此,请考虑以下示例:
HashMap<String, Integer> map = new HashMap<>();
map.put("key", 1);
System.out.println(map.get("key")); // Outputs 1
System.out.println(map.size()); // Outputs 1
map.put("key", 2);
System.out.println(map.get("key")); // Outputs 2
System.out.println(map.size()); // Still outputs 1
您的反例的问题在于您实际上在地图中没有重复。
你放116
(装箱后int
或Integer
)和"116"
(String
)。由于两者都是不同类型,因此地图区分它们,它们是不同的对象。请考虑以下示例
HashMap<Object, Integer> map = new HashMap<>();
map.put("116", 1);
System.out.println(map.size()); // Outputs 1
map.put(116, 2);
System.out.println(map.size()); // Now outputs 2
System.out.println("116".equals(116)); // Outputs false
通常,您不应使用原始类型,即使用HashMap
而不指定要使用的通用类型,例如HashMap<String, Integer>
。如果您未指定任何内容,则会使用HashMap<Object, Object>
。通过它,它允许每个Object
被放入地图。在许多情况下,您可以并且只想将其限制为特定类型。
答案 1 :(得分:0)
你没有重复。 Integer
和String
个对象的类型不同,因此&#34; 116&#34;和116不等于它们并且它们具有不同的哈希码
相同的对象在正在运行的进程中必须具有相同的哈希码
在equals方法中如果类型不等于两个对象,它将返回false
,请检查Integer等于植入
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
对于哈希代码,在你的情况下它们也不会相等:
如何计算String哈希码:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
对于Integer
哈希码,它是相同的整数值,所以在你的情况下,对于Integer
实例它将是116,所以那些将永远不会相同。
请避免使用HashMap而不指定泛型类型的原始类型,请阅读本文what-is-a-raw-type-and-why-shouldnt-we-use-it了解更多详情
答案 2 :(得分:0)
尝试以下方法:
String s123="123";
Integer i123=123;
System.out.println(s123.hashCode());
System.out.println(i123.hashCode());
System.out.println(i123.equals(s123)); // you can try s123.equals(i123) too
你甚至可以在线测试它,只需将这些行复制/输入http://www.javarepl.com/term.html - 你会看到String的哈希码为48690,Integer有123,并且它们不相同。
(当然它也适用于116,只是在输入这个答案时我没有在我面前有这个号码)