我可以在地图中保留重复包含的密钥

时间:2018-01-16 21:42:50

标签: java dictionary collections

为什么我能够将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中保留重复的键

3 个答案:

答案 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(装箱后intInteger)和"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)

你没有重复。 IntegerString个对象的类型不同,因此&#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,只是在输入这个答案时我没有在我面前有这个号码)