1. 程式人生 > >JAVA:HashMap常用方法,對於自定義類的儲存,原始碼分析

JAVA:HashMap常用方法,對於自定義類的儲存,原始碼分析

  public  static void main(String[] args) {

        //hashMap儲存結構為陣列+連結串列
        //資料儲存方式為鍵值對

        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        hashMap.put("zhangsan", 18);//增加元素
        hashMap.put("lisi", 19);
        Integer lisi = hashMap.get("lisi");//通過鍵獲取元素
        //由於通過鍵獲取值,因此key鍵相當於陣列的下標,所以不能重複,且null只能有一個是很自然的,而value不受影響
        // 因此不受限制
        /**
         * 遍歷方式有三種:
         * entrySet(),keySet(),values()
         */
        System.out.println("根據節點遍歷");
        Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> next = iterator.next();
            System.out.println(next.getKey());
        }
        System.out.println("根據key值遍歷");
        Set<String> strings = hashMap.keySet();
        Iterator<String> iterator1 = strings.iterator();
        while (iterator1.hasNext()){
            String next = iterator1.next();
            System.out.println(next);
        }
        System.out.println("根據values值遍歷");
        Collection<Integer> values = hashMap.values();
        Iterator<Integer> iterator2 = values.iterator();
        while (iterator2.hasNext()){
            Integer next = iterator2.next();
            System.out.println(next);
        }

        /**
         *
         * 對於上面存放String,Integer型別,他們對應的類底層都實現類hashcode(),equals()方法;
         * 因此對於自定義的類,必須實現hashcode(),equals()方法;
         * hashcode()方法用來計算儲存元素的雜湊值,通過雜湊值查詢儲存在陣列中的位置,雜湊值通過對key值用雜湊函式計算出來的,
         * equals()方法用來在儲存值時比較value和key是否相等,如果相等將會覆蓋,如果不能,會new entry()節點儲存新的值
         * 對於一個節點是否已經存在,必須先找位置,在比較key和value是否都相等,找位置用到雜湊函式,不同的資料型別雜湊函式不同,
         * 對於自定義的類,自己定義自己的雜湊函式
         * 為什麼要用陣列和連結串列?
         * 解決雜湊衝突,但在jdk1.8之後,對於連結串列元素超過8個元素,用的是紅黑樹,解決雜湊衝突,方便查詢
         */
        
  HashMap<Student,Integer> hashMap1=new HashMap<Student,Integer>();
  hashMap1.put(new Student("lisi",201302),2);
  hashMap1.put(new Student("lisi",201302),2);
          //必須實現hashcode()和equals()方法,否則儲存的是兩個節點,因為沒有重寫那兩個方法,put時,根據object中的hashcode()和equals()
        // 方法,因為new Student()的地址不同,因此存放了兩個節點,達不到hashmap的資料不能重複的特點,因此對於自定義類必須重寫方法,重寫方法。
        Set<Student> students = hashMap1.keySet();
        Iterator<Student> iterator3 = students.iterator();
        while (iterator3.hasNext()){
            Student next = iterator3.next();
            System.out.println(next.toString());
        }
        /**
         * hashmap中陣列的擴容方式,裡面有一個載入因子,初始為0.75,一旦陣列使用的長度達到0.75*組數長度就需要擴容,擴容方式為2的倍數;
         * 以上可以總結hashmap的特點:
         * key值不能重複,可以有一個null
         * values值可以有多個為null
         * 儲存資料不能重複,如果有key值相等而value值不等,則用新的value替換舊的value並返回舊的value;
         * 三種迭代器遍歷方法,也可以用增強for迴圈
         * 增刪改效率都比較高
         * 
         * 
         */

    }

    }
class Student {

    private String name;
    private int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return id == student.id &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, id);
    }

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