java集合框架--HashMap--put

松下一田發表於2020-12-10

一、key對應的類須重寫hashCode()與equals()方法,否則key中值相同時,仍會新增(key重複)

package com.fupng3.collectionpack;

public class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.fupng3.collectionpack;

import java.util.*;
import org.junit.Test;

public class CollectionTest {
    @Test
    public void testHashMapAdd(){
        Person p1=new Person("A",10);
        Person p2=new Person("B",11);
        Person p3=new Person("B",11);

        HashMap<Person,String> map=new HashMap<Person,String>();
        map.put(p1,"80");
        map.put(p2,"89");
        map.put(p3,"89");


        Iterator<Map.Entry<Person,String>> iterator=map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<Person,String> entry=iterator.next();
            System.out.println(entry.getKey()+"===>"+entry.getValue());
        }
}

(1)Person類不重hashCode()與equals()方法時,輸出結果為

Person{name='B', age=11}===>89
Person{name='B', age=11}===>89
Person{name='A', age=10}===>80

(2)Person類重hashCode()與equals()方法時,輸出結果為

Person{name='A', age=10}===>80
Person{name='B', age=11}===>89

二、key相等時,value值會被覆蓋

(1)判斷key相等,須同時滿足:擾動函式值相等、key值相等

p.hash == hash //擾動函式值相等
&&
((k = p.key) == key || (key != null && key.equals(k))) //key值相等

(2)測試案例1

package com.fupng3.collectionpack;

public class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        return name.equals(person.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}
package com.fupng3.collectionpack;

import java.util.*;
import org.junit.Test;

public class CollectionTest {
    @Test
    public void testHashMapAdd(){
        Person p1=new Person("A",10);
        Person p2=new Person("B",11);
        Person p3=new Person("B",11);

        HashMap<Person,String> map=new HashMap<Person,String>();
        map.put(p1,"80");
        map.put(p2,"89");
        map.put(p3,"90");


        Iterator<Map.Entry<Person,String>> iterator=map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<Person,String> entry=iterator.next();
            System.out.println(entry.getKey()+"===>"+entry.getValue());
        }
}

輸出結果為

Person{name='A', age=10}===>80
Person{name='B', age=11}===>90 //1、新增p2成功;2、修改p2的value值為90(p3並未新增成功)

(3)測試案例2

(a)Person類同(2)

(b)測試類程式碼

package com.fupng3.collectionpack;

import java.util.*;
import org.junit.Test;

public class CollectionTest {
    @Test
    public void testHashMapAdd(){
        Person p1=new Person("A",10);
        Person p2=new Person("B",11);
        Person p3=new Person("B",11);

        HashMap<Person,String> map=new HashMap<Person,String>();
        map.put(p1,"80");
        map.put(p2,"89");
        map.put(p3,"90");

        p2.name="C";
        p3.name="D";
        Iterator<Map.Entry<Person,String>> iterator=map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<Person,String> entry=iterator.next();
            System.out.println(entry.getKey()+"===>"+entry.getValue());
        }
    }
}

(c)輸出結果為

Person{name='A', age=10}===>80
Person{name='C', age=11}===>90 

(3)測試案例3

(a)Person類同(2)

(b)測試類程式碼

package com.fupng3.collectionpack;

import java.util.*;
import org.junit.Test;

public class CollectionTest {
    @Test
    public void testHashMapAdd(){
        Person p1=new Person("A",10);
        Person p2=new Person("B",11);
        Person p3=new Person("B",11);

        HashMap<Person,String> map=new HashMap<Person,String>();
        map.put(p1,"80");
        map.put(p2,"89");
        map.put(p3,"90");

        p2.name="C";
        p3.name="D";

        map.remove(p2);

        Iterator<Map.Entry<Person,String>> iterator=map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<Person,String> entry=iterator.next();
            System.out.println(entry.getKey()+"===>"+entry.getValue());
        }
    }
}

(c)輸出結果為

Person{name='A', age=10}===>80
Person{name='C', age=11}===>90

分析:執行p2.name="C"後,p2的擾動函式值hash已發生變化,所以remove時,並未定位到Person("B",11)插入的p2

相關文章