Java學習筆記31(集合架構五:set介面、雜湊表的介紹)

來源:互聯網
上載者:User

標籤:null   身份證   重寫   方法   ring   set   實現   遍曆   hashcode   

set介面的特點:

1.不包含重複元素

2.set集合沒有索引,只能用迭代器或增強for迴圈遍曆

3.set的底層是map集合

方法和Collection的方法基本一樣

 

set介面的實作類別HashSet:

1.無序集合

2.可以存入空(null)

3.不可以存在重複元素

樣本:

package demo;import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class HashSetDemo {    public static void main(String[] args) {        Set<String> set = new HashSet<String>();        set.add("abc1");        set.add("abc1");        set.add("abc2");        set.add("abc3");        set.add("abc4");        Iterator<String> i1 = set.iterator();        while(i1.hasNext()){            System.out.println(i1.next());        }    }}/*輸出:注意:這裡的輸出特點是無序的abc1abc4abc2abc3*/

 

set底層資料結構是雜湊表:

特點:儲存取出都比較快

原理:具體省略,簡單說就是鏈表數組結合體

 

對象的雜湊值:普通的一個整數

可以理解為社會安全號碼,是hashset儲存的依據

package demo;public class Person {}
package demo;public class HashDemo {    public static void main(String[] args) {        Person p = new Person();        int i = p.hashCode();        System.out.println(i);        //每次運行都會輸出不同的整數,比如1191201656                String s1 = new String("abc");        String s2 = new String("abc");        System.out.println(s1.hashCode());//96354        System.out.println(s2.hashCode());//96354        //這裡Stirng重寫hashcode方法,有對應的計算公式        //當字串的內容相同時候,運算結果就相同,因此s1和s2的雜湊值相同    }}

 

雜湊表預存程序:


1.調用對象的雜湊值

2.集合在容器內搜尋有沒有重複的雜湊值,如果沒有,存入新元素,記錄雜湊值

3.再次儲存,重複上邊的過程

4.如果有重複的雜湊值,調用後來者的equals方法,參數為前來者,結果得到true,集合判斷為重複元素,不存入

 

相同的字串如果存進去,雜湊值相同,equals方法為true,不會存入相同的

只要雜湊值相同或者equals方法為true都成立才不會存入,只要其中一條不滿足,都會儲存

 

雜湊表儲存自訂對象:

package demo;public class Person {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String toString() {        return this.name + ":" + this.age;    }    public Person() {    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }}

 

package demo;import java.util.HashSet;public class HashDemo {    public static void main(String[] args) {        HashSet<Person> setPerson = new HashSet<Person>();        setPerson.add(new Person("a",17));        setPerson.add(new Person("b",20));        setPerson.add(new Person("b",20));        setPerson.add(new Person("c",18));        System.out.println(setPerson);        //[c:18, b:20, a:17, b:20]        //發現存入了重複的元素        //所以想辦法使name和age相同的Person對象視為同一個對象        //所以需要重寫hashcode方法    }}

 

自己重寫:

 

package demo;public class Person {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String toString() {        return this.name + ":" + this.age;    }    public Person() {    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }    public int hashCode(){        return name.hashCode()+age*66;    }    public boolean equals(Object obj) {        if (this == obj) {            return true;        }        if (obj == null) {            return false;        }        if (obj instanceof Person) {            Person p = (Person) obj;            return name.equals(p.name) && age == p.age;        }        return false;    }}

 

eclipse可以協助我們寫:

package demo;public class Person {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String toString() {        return this.name + ":" + this.age;    }    public Person() {    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + age;        result = prime * result + ((name == null) ? 0 : name.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;        Person other = (Person) obj;        if (age != other.age)            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        return true;    }}

 

LinkedHashSet集合:基於鏈表的雜湊表實現,繼承HashSet,它具有順序

樣本:

package demo;import java.util.LinkedHashSet;public class LinkedHashSetDemo {    public static void main(String[] args) {        //有序的set        LinkedHashSet<Integer> link = new LinkedHashSet<Integer>();         link.add(1);        link.add(2);        link.add(3);        link.add(4);        System.out.println(link);        //[1, 2, 3, 4]    }}

 

關於hashcode和equals的一些問題,在面試中會問道:

1.兩個對象雜湊值相同,那麼equals方法一定返回true嗎?不一定

取決於如何重寫equals,如果重寫固定了它返回false,結果就一定是false

2.equals方法返回true,那麼雜湊值一定相同嗎?一定

如果類中定義一個靜態變數(static int a = 1),然後重寫hashcode返回a+1,那麼每一個對象的雜湊值都不一樣

不過java中規定:對象相等,必須具有相同的雜湊碼值,所以這裡是一定的

 

Java學習筆記31(集合架構五:set介面、雜湊表的介紹)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.