java基础巩固系列(五):ArrayList与HashSet的比较,以及HashCode分析

来源:互联网 发布:java发送socket请求 编辑:程序博客网 时间:2024/05/14 06:51

首先,我们需要知道的是ArrayList和HashSet类都在java.util包中,都是实现了Collection的类,Collection是一个标准。


然后,我们介绍下这两个类之间的区别:

1、ArrayList:相当于一个动态的数组,是一组有序的集合,当对象被添加到ArrayList时,对象会先找到第一个空缺的地方。这里有一点需要记得:放进去的是对象的引用,不是对象本身。然后,放入第二个对象,如果和第一个相同的话,依然按照顺序存放进去。也就是说,在这个有序集合里,每有一个对象就会放入一个引用,可能出现多个引用指向同一个对象的情况,但没有关系

package com.internet;import java.util.ArrayList;public class test {public static void main(String[] args){ArrayList c = new ArrayList();Integer a = new Integer(1);Integer b = new Integer(1);c.add(a);c.add(b);System.out.println(c.size()); //结果:2System.out.println(a.equals(b));//结果为true,可以看出两个对象是相等的}}
2、HashSet:当放入对象时,首先查看里面是否有这样一个对象(这里判定的是对象的地址是否相同),如果有,则不放,如果没有才会放入:

MyTest.java

package com.internet;class MyTest{int x;int y;    public  MyTest(int x,int y)    {    this.x=x ;    this.y=y ;    }}
ReflectTest.java

package com.internet;import java.util.HashSet;public class ReflectTest {public static void main(String[] args) {HashSet hs = new HashSet();MyTest t1 = new MyTest(1, 1);MyTest t2 = new MyTest(2, 2);MyTest t3 = new MyTest(1, 1);hs.add(t1);hs.add(t2);hs.add(t3);hs.add(t1);System.out.println(hs.size()); //结果:3}}
在这里,需要注意一点:在FlectTest.java中,声明了t3对象,这里的t3与t1的构造的x,y值相同,但是t1和t3都存入了hs中,

就是因为,这里说的是否有相同的对象指的是内存地址,不是数值。


其次,紧接上边的HashSet的例子,如果我们需要让t1和t3是相同,在t1存进去之后t2不能够存进去,应怎么办呢?
我们需要在MyTest.java中覆盖equals()方法:

package com.internet;import java.util.*;class MyTest1{int x;int y;    public  MyTest1(int x,int y)    {     this.x=x ;     this.y=y ;    }    @Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;MyTest1 other = (MyTest1) obj;if (x != other.x)return false;if (y != other.y)return false;return true;}}
然后,在FlectTest.java中得到的结果就是2了。

具体该怎么覆盖呢?在MyTest.java代码窗口点击右键------>找到“Source"并点击------->找到”Generate hashCode() and equals()"并点击。


还有,在对象中覆盖了equals()方法之后,当一个对象存储进了HashSet集合之中后,就不能够修改这个对象中参与计算哈希值的字段了。否则,对象修改后的哈希值与最初存进HashSet集合中的哈希值就不同了。这时,如果要删除某个存进去的对象,就不能够通过哈希值正确删除了,从而造成内存泄露。

package com.internet;import java.util.*;public class ReflectTest4{   public static void main(String[]args)   {     //面向父类的编程或者面向接口编程    Collection c1=new HashSet() ;        MyTest1 t1=new MyTest1(2,2)  ;       MyTest1 t2=new MyTest1(3,4)  ;       MyTest1 t3=new MyTest1(2,2)  ;       c1.add(t1) ;       c1.add(t2) ;       c1.add(t3) ;       c1.add(t1) ;              System.out.println(c1.size());  //结果:2                     t1.x =4;       c1.remove(t1);              System.out.println(c1.size());  //结果:2    }   }
由上边我们可以看到,t1对象没有被正确删除。因为程序修改了t1中能够生成hashcode的值x,导致生成的hashcode与存进去的不一致,不能删除。


0 0
原创粉丝点击