Obey the general contract when overriding equals

先了解equals 和 == 的区别,如果不重写equals, equals比较的仅仅只是是否引用同一个对象,==更多的是比较基本数值。当我们创建一些对象的时候。

当对象是单例模式不需要进行 equals 重写。

Reflexive: For any non-null reference values x,x.equals(x) must return true.

Symmetric:For any non-null reference values x and y,x.equals(y) must return true if and only if y.equals(x) returns true

Transitive:For any non-null reference values x,y,z,if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) must return true.

Consistent: For any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

For any non-null reference value x,x.equals(null) must return false.

以及,要明白hashcode的作用,与equals的关系。

package all;

import java.util.Collection;
import java.util.HashSet; public class Test5 { public static void main(String[] args) {
// TODO Auto-generated method stub
Collection c = new HashSet ();
Address s1 = new Address("05");
Address s2 = new Address("05");
c.add(s1);
c.add(s2);
//HashSet()有这个机制,当add的对象发现它hashcode和自己里面已经有的已经相等,自己就会进行相等的对象equals判断,判断为
//相等,set不会储存相同的值,所以就当只存了一个对象。hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
//详情 http://www.importnew.com/8701.html 关键点 一些collection的比较先从hashcode开始,所以才能快速。
System.out.println("----------------");
System.out.println(s1.equals(s2));
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(c); }
} class Address{
private String addressName;
public Address(String addressName){
this.addressName=addressName;
} public String toString(){
return this.addressName;
} @Override
public boolean equals (Object o){
if (this==o){//对象自身相等原则
return true;
}
if (o==null){//空值返回false 原则
return false;
}
if (o.getClass()!=getClass()){// 类型相同原则
return false;
} Address addr = (Address) o;//之后是实例化进行逻辑比较
if (!addr.addressName.equals(this.addressName)){
return false;
} System.out.println("Use equals!");
return true;
} @Override
public int hashCode(){//hashcode值 很重要,尤其是涉及collection。
return this.addressName.hashCode();
}
}
/*
输出以下:
Use equals!
----------------
Use equals!
true
1541
1541
[05]
会发现在分割线之上凭空多一个 use equals? 这是因为在 hashset 添加的时候,会先进行hashcode 进行比较,一样hashcode值得对象调用equals
比较得出完全一样的对象,根据hashset不重复的特性,最后只有一个值 05 ,如果试着把hashcode 方法去掉 ,则在第一步hashcode值判断就会不一样,
不会进行下一步的 equals 判断,则会输出两个 05,而实际我们希望他们是同一个对象。 */

但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;

  如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;

  如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;

  如果两个对象的hashcode值相等,则equals方法得到的结果未知。

Cosider implementing Comparable

Comparable 接口的重写有利于 排序,在遇见一些Collection 的时候 。 除了Comparable 还有Comparator ,前者是比较接口 在类中实现,一个是比较器,创建一个类来实现,代码如下。

public class Cat implements Comparable<Cat> {
private int age;
private String name;
public Cat(int age,String name){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} @Override
public int compareTo(Cat o) {//重写比较接口
// TODO Auto-generated method stub return (this.age-o.age);
} } public class MyComparator implements Comparator<Cat>{//比较器的扩展 @Override
public int compare(Cat arg0, Cat arg1) {
// TODO Auto-generated method stub
return (arg1.getAge()-arg0.getAge());
} } public class Test2 { public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ArrayList<Cat> list = new ArrayList<Cat>();
list.add(new Cat(1,"1"));
list.add(new Cat(5,"5"));
list.add(new Cat(2,"2"));
list.add(new Cat(4,"4"));
list.add(new Cat(3,"3"));
Collections.sort(list);
for (Cat a:list){
System.out.println(a.getAge());
}
Collections.sort(list, new MyComparator());
for (Cat a:list){
System.out.println(a.getAge());
} } } /*
输出
1
2
3
4
5
5
4
3
2
1
*/

Effective Java Methods Common to All Objects的更多相关文章

  1. Effective Java 05 Avoid creating unnecessary objects

    String s = new String("stringette"); // Don't do this. This will create an object each tim ...

  2. Effective Java P2 Creating and Destroying Objects

    This chapter concerns creating and destorying objects : when and how to create them, when and how to ...

  3. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  4. Effective Java 第三版笔记(目录)

    <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时 ...

  5. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  6. 【Effective Java】阅读

    Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...

  7. 《Effective Java》读书笔记 - 3.对于所有对象都通用的方法

    Chapter 3 Methods Common to All Objects Item 8: Obey the general contract when overriding equals 以下几 ...

  8. Effective Java 创建和销毁对象

    <Effective Java>阅读笔记,用适合自己理解的方式提炼该书内容.<Effective Java>是一本很实用的书,阅读方法应该是快速的领会,总结,然后应用.而非,一 ...

  9. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. Hadoop – The Definitive Guide Examples,,IntelliJ

    IntelliJ Project for Building Hadoop – The Definitive Guide Examples http://vichargrave.com/intellij ...

  2. Fiddler抓包配置具体步骤

    如何查看手机连接的无线wifi的IP? 打开手机,选择设置->进入设置页面选择WLAN->进入WLAN管理,点击手机已经连接的路由器->点击进入查看,即可看见IP地址 如何查看自己电 ...

  3. 『MXNet』第三弹_Gluon模型参数

    MXNet中含有init包,它包含了多种模型初始化方法. from mxnet import init, nd from mxnet.gluon import nn net = nn.Sequenti ...

  4. 发送http请求,get和post两种请求方式

    GET请求 GetMethod getMethod=null; String datas = "json=" + plain; HttpClient httpClient = ne ...

  5. leetcode-algorithms-32 Longest Valid Parentheses

    leetcode-algorithms-32 Longest Valid Parentheses Given a string containing just the characters '(' a ...

  6. HTTP及RFC解析。

    HTTP协议描述的是发送方与接收方的通信协议,通过两方的自觉遵守而存在,当然有不少的浏览器并没有百分百遵守这份协议.HTTP是运行于应用层的协议,基于TCP协议而运作.基本上是客户/服务器对答模式,其 ...

  7. MongoDB 教程(二):MongoDB 简介

    概述: MongoDB 旨在为WEB应用提供可扩展.高性能的数据存储解决方案. MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成. MongoDB 文档类似于 ...

  8. Oracle Log Block Size

    Although the size of redo entries is measured in bytes, LGWR writes the redo to the log files on dis ...

  9. 如何把一个杯子卖到上万元,不学你就OUT了

    我们可以看看一个产品卖到多少钱需要占有什么样的资源: 第1种卖法:卖产品本身的使用价值,只能卖3元/个 如果你将他仅仅当一只普通的杯子,放在普通的商店,用普通的销售方法,也许它最多只能卖3元钱,还可能 ...

  10. nginx支持HTTP2的配置过程

    一.获取安装包 http://zlib.net/zlib-1.2.11.tar.gz https://www.openssl.org/source/openssl-1.0.2e.tar.gz (ope ...