首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

黑马软件工程师_集合学习之hashset学习笔记

2013-04-09 
黑马程序员_集合学习之hashset学习笔记------- android培训、java培训、期待与您交流! ----------在collecti

黑马程序员_集合学习之hashset学习笔记

------- android培训、java培训、期待与您交流! ----------

在collection中,除了list派系之外,还有一个set派系

 

Set中元素是无序的,也就是存入和取出顺序不一定一致,而且元素不能重复。

更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1e2,并且最多包含一个 null 元素

 

查看set接口的功能,才发现set和collection是一致的。

 

 

在set接口下,有两个我们常用的类比较重要

HashSet:它的底层数据结构式哈希表

TreeSet

 

什么叫做哈希表?

比如,我们定义了两个Demo对象

class Demo

{

}

Demo d1 = new Demo();

      Demod2 = new Demo();

     

     System.out.println(d1);//输出day1.Demo@150bd4d

      System.out.println(d2);//输出day1.Demo@1bc4459

 

  这是定义了一个哈希结构的集合。将上述两个对象的哈希值存入到集合中

  

150bd4d,1bc4459

 

  

 

 


注意,存放的顺序不是按照你存入的数据去定义的。这也就是和arraylist的区别

顺序是按照哈希值的顺序去存入的。

 

在我们去取的时候,是按照表里边的顺序去取。

 

经过我的测试,在其类中加入了

class Demo

{

    publicinthashCode()

    {

       System.out.println("1");

      

       return 0;

    }

}

已验证是否在进入集合中时候,调用了自身的hashCode()方法。

Demo d1 = new Demo();

      Demod2 = new Demo();

     HashSet<Demo> hs = newHashSet<Demo>();

     

     hs.add(d1);

     hs.add(d2);

 

输出了

1

1

故以上得以证明确实调用了对象的hashcode方法。

 

切记,哈希表是按照哈希值来存储的。当哈希值一样的时候,

还有一次校验的方式。就是使用看是否是同一个对象。也就是调用对象的equals

方法。 如果equals不等的话,就会在该hashcode对应的地址顺延

如两个hashcode都为1,但是equals不同

则   1(同一地址,这里存放一个对象)------1(另一个对象),也就是

  

 黑马软件工程师_集合学习之hashset学习笔记

 

 

 

 

 

如果hashcode的值不一样,那么没有必要计较equals方法了

这里突然想到了equals和==的区别,

==比较的是两个对象的内存地址是否一致。

Demo d1 = newDemo();

Demo d2 = new Demo();

则d1==d2为false

Demo d1 = newDemo();

Demo d2 = d1;

则d1==d2为true

当使用equals方法时候,如果对象实现了equals方法,则使用其自己的。

如果没有实现,则调用从object中得到的。

publicbooleanequals(Object obj){

    return (this ==obj);

    }

其实也就是比较的内存地址了。

也就是如果你没有实现equals方法,则==和equals得到的值一样。

 

其实hashset就是hash表结构的。。。

 

HashSet<String>hs = new HashSet<String>();

     

     hs.add("java01");

     hs.add("java02");

     hs.add("java03");

     hs.add("java03");

      for(Strings:hs)

      {

        System.out.println(s);

      }

java02

java03

java01

这里我们验证了不可重复和无序的规律

 

 

这里我们来说往hashSet集合中存入自定义对象。

 

classPersonDemo

{

    privateStringname;

    publicPersonDemo(String name,int age) {

       super();

       this.name =name;

       this.age =age;

    }

    privateintage;

    publicString getName() {

       returnname;

    }

    publicvoidsetName(String name) {

       this.name =name;

    }

    publicintgetAge() {

       returnage;

    }

    publicvoidsetAge(int age) {

       this.age =age;

    }

   

    publicinthashCode()

    {

       System.out.println("code");

       returnname.hashCode()+age;

    }

    publicboolean equals(Objecto)

    {

            System.out.println(“equals”);

       PersonDemo p = (PersonDemo)o;

       returnname.equals(p.name)&&age==p.age;

    }

   

}

上边我们定义了一个对象并实现了equals和hashCode(根据具体的比较形式)。

 

并创建

HashSet<PersonDemo>hs = new HashSet<PersonDemo>();

       hs.add(newPersonDemo("dabin",11));

       hs.add(newPersonDemo("dabin1",12));

       hs.add(newPersonDemo("dabin2",13));

       hs.add(newPersonDemo("dabin2",13));

 

控制台输出

hashcode

hashcode

hashcode

hashcode

equals

原理如下。

Dabin对象调用hashcode的到一个哈希吗。放到内存中

Dabin1对象调用hashcode的到一个哈希吗。与dabin比较,hashcode不同,放到内存中。

Dabin2对象调用hashcode的到一个哈希吗。与dabin1和2比较,hashcode不同,放到内存中。

当再次存入dabin2的时候,由于hashcode码一样,故调用了equals方法。

Dabin(码)

Dabin1(码)

Dabin2(码)

 由于equals方法一致,所以。Dabin2没有被放入。

 

 

 

 

 

 

 

综上,hashset是通过hashcode和euqals保证元素的一致性。

 

当说完增加元素的时候,我们说一说删除和寻找元素的原理

HashSet<PersonDemo>hs = new HashSet<PersonDemo>();

       hs.add(newPersonDemo("dabin",11));

       hs.add(newPersonDemo("dabin1",12));

       System.out.println(hs.contains(newPersonDemo("dabin1",12)));

 

输出为

hashcode.....dabin

hashcode.....dabin1

hashcode.....dabin1//得到了要寻找的hash值,比较后,存在一个hashcode一致的对象,则调用equals做进一步判断

equals//也一致。

True//所以发现元素包含。

Remove也是同样的比较方式。。。

 

但是对于arraylist来说,只是去比较equals方法,与hashcode无关。

 


热点排行