国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Java的HashSet類(lèi)

2019-11-15 00:51:07
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
java的HashSet類(lèi)

如果要查找一個(gè)集合中是否包含了某個(gè)對(duì)象,那么就需要把這個(gè)對(duì)象和這個(gè)集合中的每個(gè)對(duì)象依次進(jìn)行比較和判斷,直到找到這個(gè)對(duì)象為止,或者把所有對(duì)象都比較一次為止(如果最后一個(gè)對(duì)象才是要查找的對(duì)象,或者集合中沒(méi)有包含要查找的對(duì)象)。當(dāng)集合中的對(duì)象數(shù)量較多時(shí),效率就很低。為了提高效率,提出了Hash算法。Hash算法對(duì)每一個(gè)對(duì)象都計(jì)算出一個(gè)Hash碼,根據(jù)Hash碼把對(duì)象分配到某個(gè)存儲(chǔ)區(qū)域中,比如一個(gè)集合包含了很多人,根據(jù)國(guó)籍,中國(guó)人是一個(gè)存儲(chǔ)區(qū)域,美國(guó)人是一個(gè)存儲(chǔ)區(qū)域,英國(guó)人是一個(gè)存儲(chǔ)區(qū)域,......。這樣如果要查找該集合是否包含了某個(gè)中國(guó)人,就到中國(guó)人的存儲(chǔ)區(qū)域去比較就行了,這樣大大提高了效率。

Java中實(shí)現(xiàn)了Hash的集合是HashSet。HashSet查找某個(gè)對(duì)象時(shí),首先用hashCode()方法計(jì)算出這個(gè)對(duì)象的Hash碼,然后再根據(jù)Hash碼到相應(yīng)的存儲(chǔ)區(qū)域用equals()方法查找,從而提高了效率。由于是集合,所以同一個(gè)對(duì)象只能有一個(gè)。

hashSet的例子如下所示:

package my;import java.util.HashSet;import java.util.Set;class Person{        // 性別    String sex;    // 姓名    String name;    // 身高    Double hei;    // 體重    Double wei;        public Person(String n, String s, Double h, Double w){            this.name=n;        this.sex=s;        this.hei=h;        this.wei=w;                }        public String toString(){        return "/n姓名:"+this.name+"  性別:"+this.sex+"  身高:"+this.hei+"  體重:"+this.wei;            }    }public class myHS {    PRivate static Set<Person> mySet = new HashSet<Person>();    public static void main(String[] args) {        mySet.add(new Person("Tom","Male",170.0,70.0));            mySet.add(new Person("Peter","Male",175.0,70.0));        mySet.add(new Person("Kate","Female",168.0,60.0));        mySet.add(new Person("Alice","Female",161.0,55.0));        mySet.add(new Person("Jack","Male",190.0,95.0));        mySet.add(new Person("Jack","Male",190.0,95.0));        System.out.println(mySet);    }}

以上例子先定義了Person類(lèi),然后定義了一個(gè)HashSet,并加入了5個(gè)Person到該集合,其中1個(gè)人加入了兩次,運(yùn)行結(jié)果如下:

可見(jiàn)Jack是同一個(gè)人,卻在集合中出現(xiàn)了兩次,這是什么原因呢?這是因?yàn)椋琍erson是Object的子類(lèi),而Object類(lèi)的equals()方法是根據(jù)對(duì)象的內(nèi)存地址來(lái)判斷兩個(gè)對(duì)象是否相等的,由于兩次插入的Jack的內(nèi)存地址肯定不相同,所以判斷的結(jié)果是不相等,所以?xún)纱味疾迦肓恕S谑牵覀冃枰矊?xiě)equals()方法來(lái)判斷兩個(gè)對(duì)象是否是同一個(gè)對(duì)象。

    // 覆寫(xiě)equals方法    public boolean equals (Object obj){        // 地址相等,則肯定是同一個(gè)對(duì)象        if(this==obj){            return true;        }        // 類(lèi)型不同,則肯定不是同一類(lèi)對(duì)象        if(!(obj instanceof Person)){            return false;        }         // 類(lèi)型相同,向下轉(zhuǎn)型        Person per=(Person) obj;        // 如果兩個(gè)對(duì)象的姓名和性別相同,則是同一個(gè)人        if(this.name.equals(per.name)&&this.sex.equals(per.sex))            return true;        return false;    }

覆寫(xiě)equals()方法以后,運(yùn)行結(jié)果如下:

可見(jiàn)Jack仍然被插入了兩次,這是什么原因呢?這是因?yàn)镺bject的Hash碼返回的是對(duì)象的Hash地址,而兩個(gè)對(duì)象的Hash地址肯定是不相等的,所以6次插入的對(duì)象被存儲(chǔ)在6個(gè)存儲(chǔ)區(qū)域,equals()方法根本沒(méi)有運(yùn)行。于是,還需要覆寫(xiě)hashCode()方法,根據(jù)姓名來(lái)計(jì)算對(duì)象的Hash碼。

    // 覆寫(xiě)hashCode方法      public int hashCode(){        return this.name.hashCode();    }

運(yùn)行結(jié)果如下:

可見(jiàn),Jack只插入了一次,終于正確了。如果根據(jù)性別來(lái)計(jì)算對(duì)象的Hash碼,結(jié)果也是正確的,Jack也只會(huì)被插入1次。但是,如果兩個(gè)對(duì)象的性別不同,如下所示:

        mySet.add(new Person("Jack","Male",190.0,95.0));        mySet.add(new Person("Jack","Female",190.0,95.0));

則兩個(gè)對(duì)象都會(huì)被插入:

這是因?yàn)殡m然兩個(gè)對(duì)象的Hash碼相同(不論是按照姓名,還是按照性別來(lái)計(jì)算,Hash碼都是相同的),但是equals()方法判斷這兩個(gè)對(duì)象不相等,于是都插入了。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 五台县| 睢宁县| 项城市| 九江县| 阳朔县| 德格县| 南投县| 徐汇区| 平遥县| 彭州市| 枣阳市| 洪洞县| 盈江县| 荆门市| 江阴市| 临夏市| 安化县| 五大连池市| 万山特区| 连江县| 和平县| 资兴市| 崇阳县| 阿瓦提县| 鄄城县| 酒泉市| 呼伦贝尔市| 手游| 盐亭县| 建水县| 山东| 昌平区| 东辽县| 丰镇市| 淄博市| 古交市| 潮安县| 岐山县| 磐石市| 五华县| 安乡县|