ArrayLIst类使用contains方法时要注意:放入ArrayList中的类必须要重写equals方法(既然equals重写了,那么 hash方法也应该重写,这两个方法一般同时重写);如果不重写默认用的是object类中的equals,他比较的是两个对象是否在同一个内存地址 (和==作用相同),这样的话arraylist类中的contains方法就不能正常工作。举例如下:

情况一:准备放入的类不重写equals方法。

public class Test

{

private String str;

public Test(String s)

{this.str=s;}

public static void main(String[] args)

{

List list=new ArrayList();

Test t1=new Test("test");

Test t2=new Test("test");

list.add(t1);

System.out.println(t1.equals(t2));
//调用的是Object类的equals方法,比较是不是在同一个内存空间

System.out.println(list.contains(t2));
//arraylist对象调用contains方法时,实际使用的是从object继承而来的equals,比较是否在同一个内存空间

}

}

打印结果:

false

false

情况二:重写Test的equals方法

public class Test

{

private String str;

public boolean equals(Object o)

{

if(o==this)

return true;

if(o instancesof Test)

{

Test test=(Test)o;

return str.equals(test.str);

}

return false;

}

public Test(String s)

{this.str=s;}

public static void main(String[] args)

{

List list=new Arraylist();

Test t1=new Test("test");

Test t2=new Test("test");

list.add(t1);

System.out.println(t1.equals(t2));

System.out.println(list.contains(t2));//由于t1与t2有相同的值,那么此时list调用contains(t2)判断的是list对象中是否已有值和t2的值相同的对象

}

}

打印结果:

true

true

结果:可见Test类中,重写equals后,调用Arraylist对象的contains方法时可以正常工作。此时,list.contains(t2)方法判断的是该list对象中是否已有与t2对象的值相同的对象。

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,
当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,
该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true 
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较
两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,
在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,
都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,
但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,
如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode() 重写hashCode()的主要原因是默认从Object继承来的hashCode是基于对象的ID实现的。如果你重载了equals,
比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。
这样,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值
去查找他们的时候,则根本找不到。
还可以参考http://fhuan123.iteye.com/blog/1452275

随机推荐

  1. Unix下五种IO模型

    http://blog.chinaunix.net/uid-25324849-id-247813.html 1. I/O模型 Unix下共有五种I/O模型 a. 阻塞I/O b. 非阻塞I/O c. ...

  2. shell脚本常见错误

    一.引言 想要学习使用shell脚本,却在开始的时候遇到很多不顺利,都是一些小细节的东西,所以在此记录一下. 二.各种细节问题 1.变量作为赋值对象时不需要添加$,取值时需要,也就是说,这个$就是取值 ...

  3. 2016CCPC东北地区大学生程序设计竞赛 1001 HDU5922

    链接http://acm.hdu.edu.cn/showproblem.php?pid=5922 题意:最小生成树,但边的权值是连接两点的最小公倍数 解法:不要真的写最小生成树啦,只要其他点和第一点相 ...

  4. anroid

    http://mirrors.neusoft.edu.cn/more.we#android http://www.cnblogs.com/youxilua/archive/2013/05/20/308 ...

  5. 【Thread】多线程的异常处理?

    线程中处理异常是个头疼的问题,在异步的代码中,如何将异常捕获. 捕获异常后,将异常反馈给开发者,或用户.一般来说,反馈给开发者,多数方式在是日志中打印异常日志:而反馈给用户,多数是在界面上友好提示(比 ...

  6. easyUI学习网站

    http://www.runoob.com/jeasyui/plugins-form-timespinner.html http://www.jeasyui.net/plugins/178.html ...

  7. assert函数

    这个函数在<cassert>里面,通常用来调试程序. eg: int i=1: assert(i==1):/什么也不做 assert(i==2)://程序会异常退出

  8. Web自定义协议,BS端启动CS端,

    实例 1.准备CS项目,windows窗体应用程序,拖进来一个label控件来接受BS的参数,并显示,右击生成,复制该文件的bin目录下的exe,例如放在以下路径,例如C:\\simu\\下, 2.编 ...

  9. UVA 11584 一 Partitioning by Palindromes

    Partitioning by Palindromes Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %l ...

  10. RabbitMQ在CentOS上的简单安装配置

    安装 1.依赖Erlang,yum install erlang安装之 2.去官网下载Fedora/RHEL的rpm包,rpm -ivh rabbitmq-server-*.noarch.rpm 安装 ...