Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap冲突示例不起作用_Java_Hashmap_Collision - Fatal编程技术网

Java HashMap冲突示例不起作用

Java HashMap冲突示例不起作用,java,hashmap,collision,Java,Hashmap,Collision,我的理解是,Java对HashMap的实现使用“bucket”,它指向一个值列表来处理冲突,并且只有当键的hashCode()和对象的equals()对于被添加的对象及其冲突的对象都相同时,对象才会被覆盖 我尝试使用HashMap来查看碰撞行为,但无论我做什么,它似乎总是覆盖 我在这里做错了什么(注意我故意将“count”从hashCode和equals方法中漏掉) hashmap中的键是散列的,而不是值。在本例中,您正在调用put(key,node),并且key是常量,因此第二个put将覆盖第

我的理解是,Java对HashMap的实现使用“bucket”,它指向一个值列表来处理冲突,并且只有当键的hashCode()和对象的equals()对于被添加的对象及其冲突的对象都相同时,对象才会被覆盖

我尝试使用HashMap来查看碰撞行为,但无论我做什么,它似乎总是覆盖

我在这里做错了什么(注意我故意将“count”从hashCode和equals方法中漏掉)


hashmap中的键是散列的,而不是值。在本例中,您正在调用
put(key,node)
,并且key是常量,因此第二个
put将覆盖第一个。如果节点是键,那么您将有两个条目。

哈希映射中的键是散列的,而不是值。在本例中,您正在调用
put(key,node)
,并且key是常量,因此第二个
put将覆盖第一个。如果节点是键,那么您将有两个条目。

您应该查看键而不是值。

您应该查看键而不是值。

如果您阅读,您将注意到
put()
方法定义如下

put(对象键、对象值)

将指定的值与此映射中的指定键相关联

使用同一个键调用
put()
两次时,它将覆盖与该键关联的原始值

除此之外,该表使用键的散列(而不是值)来查找正确的bucket

除此之外,你对这门课的理解是正确的

但是,我不相信您可以从公共API查看冲突,因为这很可能是在类中处理的。

如果您阅读了,您会注意到
put()
方法定义如下

put(对象键、对象值)

将指定的值与此映射中的指定键相关联

使用同一个键调用
put()
两次时,它将覆盖与该键关联的原始值

除此之外,该表使用键的散列(而不是值)来查找正确的bucket

除此之外,你对这门课的理解是正确的


但是,我不相信您可以从公共API查看冲突,因为这很可能是在类内部处理的。

下面是使用HashMap的更新代码。我还更改了equals()方法以包含count字段,但将其从hashCode()方法中删除。这将成功创建冲突,如果使用调试器查看HashMap,您可以看到它在发生冲突的bucket中构建的列表:

public class HashMapTest {

public static void main(String[] args) {
    HashMapTest test = new HashMapTest();
    test.execute();
}

public void execute() {
    HashMap<Node, Node> nodeMap = new HashMap<Node, Node>();
    Node node1 = new Node("data1", 1);
    Node node2 = new Node("data2", 2);
    Node node3 = new Node("data1", 2);
    Node node4 = new Node("data1", 1);

    System.out.println("node1 hash: " + node1.hashCode());
    System.out.println("node2 hash: " + node2.hashCode());
    System.out.println("node3 hash: " + node3.hashCode());
    System.out.println("node1 hash == node2 hash? " + (node1.hashCode() == node2.hashCode() ? "true" : "false"));
    System.out.println("node2 hash == node3 hash? " + (node2.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1 hash == node3 hash? " + (node1.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1.equals(node2)? " + (node1.equals(node2) ? "true" : "false"));
    System.out.println("node2.equals(node3)? " + (node2.equals(node3) ? "true" : "false"));
    System.out.println("node1.equals(node3)? " + (node1.equals(node3) ? "true" : "false"));
    System.out.println("");

    nodeMap.put(node1, node1);
    System.out.println("added node1 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    nodeMap.put(node2, node2);
    System.out.println("added node2 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    // note that if node4 is used then it replaces the value that stored node1
    nodeMap.put(node3, node3);
    System.out.println("added node3 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
}

protected class Node {

    private String data;

    private Integer count;

    public Node(String data, Integer count) {
        this.data = data;
        this.count = count;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Node other = (Node) obj;
        if (!getOuterType().equals(other.getOuterType()))
            return false;
        if (count == null) {
            if (other.count != null)
                return false;
        }
        else
            if (!count.equals(other.count))
                return false;
        if (data == null) {
            if (other.data != null)
                return false;
        }
        else
            if (!data.equals(other.data))
                return false;
        return true;
    }


    public String getData() {
        return data;
    }


    public void setData(String data) {
        this.data = data;
    }


    public Integer getCount() {
        return count;
    }


    public void setCount(Integer count) {
        this.count = count;
    }

    private HashMapTest getOuterType() {
        return HashMapTest.this;
    }

}

下面是使用HashMap的更新代码。我还更改了equals()方法以包含count字段,但将其从hashCode()方法中删除。这将成功创建冲突,如果使用调试器查看HashMap,您可以看到它在发生冲突的bucket中构建的列表:

public class HashMapTest {

public static void main(String[] args) {
    HashMapTest test = new HashMapTest();
    test.execute();
}

public void execute() {
    HashMap<Node, Node> nodeMap = new HashMap<Node, Node>();
    Node node1 = new Node("data1", 1);
    Node node2 = new Node("data2", 2);
    Node node3 = new Node("data1", 2);
    Node node4 = new Node("data1", 1);

    System.out.println("node1 hash: " + node1.hashCode());
    System.out.println("node2 hash: " + node2.hashCode());
    System.out.println("node3 hash: " + node3.hashCode());
    System.out.println("node1 hash == node2 hash? " + (node1.hashCode() == node2.hashCode() ? "true" : "false"));
    System.out.println("node2 hash == node3 hash? " + (node2.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1 hash == node3 hash? " + (node1.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1.equals(node2)? " + (node1.equals(node2) ? "true" : "false"));
    System.out.println("node2.equals(node3)? " + (node2.equals(node3) ? "true" : "false"));
    System.out.println("node1.equals(node3)? " + (node1.equals(node3) ? "true" : "false"));
    System.out.println("");

    nodeMap.put(node1, node1);
    System.out.println("added node1 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    nodeMap.put(node2, node2);
    System.out.println("added node2 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    // note that if node4 is used then it replaces the value that stored node1
    nodeMap.put(node3, node3);
    System.out.println("added node3 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
}

protected class Node {

    private String data;

    private Integer count;

    public Node(String data, Integer count) {
        this.data = data;
        this.count = count;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Node other = (Node) obj;
        if (!getOuterType().equals(other.getOuterType()))
            return false;
        if (count == null) {
            if (other.count != null)
                return false;
        }
        else
            if (!count.equals(other.count))
                return false;
        if (data == null) {
            if (other.data != null)
                return false;
        }
        else
            if (!data.equals(other.data))
                return false;
        return true;
    }


    public String getData() {
        return data;
    }


    public void setData(String data) {
        this.data = data;
    }


    public Integer getCount() {
        return count;
    }


    public void setCount(Integer count) {
        this.count = count;
    }

    private HashMapTest getOuterType() {
        return HashMapTest.this;
    }

}

好吧,这是有道理的。我可以修改它以使用HashMap并更改hashCode()和equals()方法以获得冲突,我看到它在键的hashCode()映射到的bucket中构建列表。但是,我注意到,如果传递给put(K,V)的键等于另一个键,那么它会覆盖该值。我认为它只是使用hashCode()来标识bucket,然后使用equal()来表示其中的值。显然,如果key equal()是另一个键,那么它将替换关联的值。一旦我超过8小时的限制来回答我的问题,我将发布代码来突出这一区别。它使用
hashCode()
来标识bucket,并使用键上的
equal()
方法。在成功检索值之前,映射不知道与键关联的值是什么,因此无法对该值使用
equal()
方法。
HashMap
的要点是键与值的1:1映射,如果一个键映射到多个值,那么它就不是一个非常有效的映射,因为不可能检索所有值!好吧,这是有道理的。我可以修改它以使用HashMap并更改hashCode()和equals()方法以获得冲突,我看到它在键的hashCode()映射到的bucket中构建列表。但是,我注意到,如果传递给put(K,V)的键等于另一个键,那么它会覆盖该值。我认为它只是使用hashCode()来标识bucket,然后使用equal()来表示其中的值。显然,如果key equal()是另一个键,那么它将替换关联的值。一旦我超过8小时的限制来回答我的问题,我将发布代码来突出这一区别。它使用
hashCode()
来标识bucket,并使用键上的
equal()
方法。在成功检索值之前,映射不知道与键关联的值是什么,因此无法对该值使用
equal()
方法。
HashMap
的要点是键与值的1:1映射,如果一个键映射到多个值,那么它就不是一个非常有效的映射,因为不可能检索所有值!顺便说一下,您可以简化
hashCode
方法以
返回数据=无效的data.hashCode():0
不需要先加1,然后再乘以31。顺便说一下,您可以简化
hashCode
方法以
返回数据=无效的data.hashCode():0不需要先加1再乘以31。
public class HashMapTest {

public static void main(String[] args) {
    HashMapTest test = new HashMapTest();
    test.execute();
}

public void execute() {
    HashMap<Node, Node> nodeMap = new HashMap<Node, Node>();
    Node node1 = new Node("data1", 1);
    Node node2 = new Node("data2", 2);
    Node node3 = new Node("data1", 2);
    Node node4 = new Node("data1", 1);

    System.out.println("node1 hash: " + node1.hashCode());
    System.out.println("node2 hash: " + node2.hashCode());
    System.out.println("node3 hash: " + node3.hashCode());
    System.out.println("node1 hash == node2 hash? " + (node1.hashCode() == node2.hashCode() ? "true" : "false"));
    System.out.println("node2 hash == node3 hash? " + (node2.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1 hash == node3 hash? " + (node1.hashCode() == node3.hashCode() ? "true" : "false"));
    System.out.println("node1.equals(node2)? " + (node1.equals(node2) ? "true" : "false"));
    System.out.println("node2.equals(node3)? " + (node2.equals(node3) ? "true" : "false"));
    System.out.println("node1.equals(node3)? " + (node1.equals(node3) ? "true" : "false"));
    System.out.println("");

    nodeMap.put(node1, node1);
    System.out.println("added node1 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    nodeMap.put(node2, node2);
    System.out.println("added node2 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
    System.out.println("");

    // note that if node4 is used then it replaces the value that stored node1
    nodeMap.put(node3, node3);
    System.out.println("added node3 to hash map");
    System.out.println("hash map size: " + nodeMap.size());
    System.out.println("hash map entry set size: " + nodeMap.entrySet().size());
    System.out.println("hash map contains node1? " + (nodeMap.containsValue(node1) ? "true" : "false"));
    System.out.println("hash map contains node2? " + (nodeMap.containsValue(node2) ? "true" : "false"));
    System.out.println("hash map contains node3? " + (nodeMap.containsValue(node3) ? "true" : "false"));
    System.out.println("node1's count from map: " + nodeMap.get(node1).getCount());
}

protected class Node {

    private String data;

    private Integer count;

    public Node(String data, Integer count) {
        this.data = data;
        this.count = count;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Node other = (Node) obj;
        if (!getOuterType().equals(other.getOuterType()))
            return false;
        if (count == null) {
            if (other.count != null)
                return false;
        }
        else
            if (!count.equals(other.count))
                return false;
        if (data == null) {
            if (other.data != null)
                return false;
        }
        else
            if (!data.equals(other.data))
                return false;
        return true;
    }


    public String getData() {
        return data;
    }


    public void setData(String data) {
        this.data = data;
    }


    public Integer getCount() {
        return count;
    }


    public void setCount(Integer count) {
        this.count = count;
    }

    private HashMapTest getOuterType() {
        return HashMapTest.this;
    }

}
node1 hash: 1077170390
node2 hash: 1077170391
node3 hash: 1077170390
node1 hash == node2 hash? false
node2 hash == node3 hash? false
node1 hash == node3 hash? true
node1.equals(node2)? false
node2.equals(node3)? false
node1.equals(node3)? false

added node1 to hash map
hash map size: 1
hash map entry set size: 1
hash map contains node1? true
hash map contains node2? false
hash map contains node3? false
node1's count from map: 1

added node2 to hash map
hash map size: 2
hash map entry set size: 2
hash map contains node1? true
hash map contains node2? true
hash map contains node3? false
node1's count from map: 1

added node3 to hash map
hash map size: 3
hash map entry set size: 3
hash map contains node1? true
hash map contains node2? true
hash map contains node3? true
node1's count from map: 1