Object的方法equals,hashCode,toString,clone。另外Comparable接口的方法
2011-08-12 11:39
633 查看
1、equals 方法和hashCode 方法实现示例:
继承时,equals 方法和hashCode 方法实现示例
2、toString 方法现实示例
规则:
a、对象用大括号包围 {....}
b、对象内的属性用中括号包围 [.....] ,各个属性之间用逗号分隔(,)
c、属性的表示格式为:$name=GongQiang
如下对象,如下toString 方法显示
对集合的信息打印帮助类:
3、clone 方法实现示例(实现 Cloneable 接口)
限制:对象的field 也为对象,则该field 不能声明为 final !
原因:final 域,有两种方式来初始化,1、直接赋值;2、构造时赋值
当深度克隆时,会有如下语句:
要正确实现某个类的 clone 方法
1、父类的 clone 方法必须都正确实现
2、类的对象域还不能声明为 final
可见 clone 方法的限制还是蛮多的,可以自定义copy 的方法:copy constructor 或 copy factory
4、Comparable 的 compareTo 方法
注意:子类继承父类的 compareTo 方法时,要保存比较的对称性!
因而加了一个判断,是否为同一 Class !
compareTo 方法与 equals 方法不一致,即:(x.compareTo(y)==0) != (x.equals(y))
示例如下:
public class ComparableVSEqeal {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
System.out.println("bd1 equals bd2: " + bd1.equals(bd2));
Set<BigDecimal> set = new HashSet<BigDecimal>();
set.add(bd1);
set.add(bd2);
CollectionPrintHelper.printCollection(set);
System.out.println("-------------------");
System.out.println("bd1 compareTo bd2: " + bd1.compareTo(bd2));
set = new TreeSet<BigDecimal>(set);
CollectionPrintHelper.printCollection(set);
}
}输出结果:
bd1 equals bd2: false
[0]:1.0
[1]:1.00
-------------------
bd1 compareTo bd2: 0
[0]:1.0
排序时有多个项:
public int compareTo(PhoneNumber pn) {
// Compare area codes
if (areaCode < pn.areaCode)return -1;
if (areaCode > pn.areaCode)return 1;
// Area codes are equal, compare prefixes
if (prefix < pn.prefix)return -1;
if (prefix > pn.prefix)return 1;
// Area codes and prefixes are equal, compare line numbers
if (lineNumber < pn.lineNumber)return -1;
if (lineNumber > pn.lineNumber)return 1;
return 0; // All fields are equal
}
public class EqualHashCodeTest { private boolean b; private int i; private float f; private double d; private String s; public EqualHashCodeTest() { super(); } public EqualHashCodeTest(boolean b, int i, float f, double d, String s) { super(); this.b = b; this.i = i; this.f = f; this.d = d; this.s = s; } //get/set方法 @Override public boolean equals(Object object) { if(object==null || getClass()!=object.getClass()){ return false; } EqualHashCodeTest hct = (EqualHashCodeTest) object; return b==hct.isB() && i==hct.getI() && 0==Float.compare(f, hct.getF()) && 0==Double.compare(d, hct.getD()) && s==null ? false : s.equals(hct.getS()); //虽然 null == null,但是这没有意义!所以这里返回false } @Override public int hashCode() { int result = 17; result = 37*result + Boolean.valueOf(b).hashCode(); result = 37*result + Integer.valueOf(i).hashCode(); result = 37*result + Float.valueOf(f).hashCode(); result = 37*result + Double.valueOf(d).hashCode(); result = 37*result + (s==null ? 0 : s.hashCode()); return result; } }
继承时,equals 方法和hashCode 方法实现示例
class ExtendEqualHashCode extends EqualHashCodeTest{ private String extendName; public String getExtendName() { return extendName; } public void setExtendName(String extendName) { this.extendName = extendName; } public ExtendEqualHashCode() { super(); this.extendName = "DEFAULT"; } public ExtendEqualHashCode(boolean b, int i, float f, double d, String s, String name) { super(b, i, f, d, s); this.extendName = name; } /** * 父类的equals 方法会检查 * 1、object 是否为null * 2、比较的两对象是否为同一 Class 对象 */ @Override public boolean equals(Object object) { return super.equals(object) && extendName == null ? false : ((ExtendEqualHashCode)object).getExtendName().equals(extendName); } @Override public int hashCode() { int result = super.hashCode(); result = 37*result + (extendName==null?0:extendName.hashCode()); return result; } }
2、toString 方法现实示例
规则:
a、对象用大括号包围 {....}
b、对象内的属性用中括号包围 [.....] ,各个属性之间用逗号分隔(,)
c、属性的表示格式为:$name=GongQiang
class PeopleForTest{ private String name; private String sex; private int age; public PeopleForTest() { super(); } public PeopleForTest(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } //get/set 方法 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sex == null) ? 0 : sex.hashCode()); return result; } @Override public boolean equals(Object obj) { if( obj == null || getClass() != obj.getClass() ){ return false; } PeopleForTest people = (PeopleForTest)obj; return (age == people.age) && stringEquals(name, people.name) && stringEquals(sex, people.sex); } private boolean stringEquals( String s1, String s2 ){ return s1 == null ? false : s1.equals(s2); } @Override public String toString() { String nameString = "[$name=" + name + "]"; String sexString = "[$sex=" + sex + "]"; String ageString = "[$age=" + age + "]"; return "{" + nameString +","+ sexString + "," + ageString +"}"; } }
如下对象,如下toString 方法显示
PeopleForTest p = new PeopleForTest( "GongQiang", "man", 24); System.out.println( p );
//output {[$name=GongQiang],[$sex=man],[$age=24]}
对集合的信息打印帮助类:
public class CollectionPrintHelper { //Used for print array public static <T> void printArrays( T[] array ){ if( array == null ){ System.out.println( "Array is null!" ); return; } int index = 0; for( T e : array ){ System.out.println( "[" + (index++) +"]:" + e ); } } //Used for print Collection public static <E> void printCollection( Collection<E> c){ if( c== null){ System.out.println( "Collection is null!" ); return; } int index = 0; for( E e : c){ System.out.println( "[" + (index++) +"]:" + e ); } } //Used for print Map public static <K, V> void printMap( Map<K, V> map ){ if( map == null ){ System.out.println("Map is null!"); return; } int index = 0; for( Entry<K, V> entry : map.entrySet() ){ String key = entry.getKey().toString(); String value = entry.getValue().toString(); System.out.print( "[" + (index++)+ "]:"); System.out.println(key + "=" + value); } } }
3、clone 方法实现示例(实现 Cloneable 接口)
限制:对象的field 也为对象,则该field 不能声明为 final !
原因:final 域,有两种方式来初始化,1、直接赋值;2、构造时赋值
当深度克隆时,会有如下语句:
m.hireDay = (Date) hireDay.clone();如果hireDay 声明为final ,则语法错误!
class Member implements Serializable ,Cloneable ,Comparable<Member>{ private static final long serialVersionUID = 259178685941754554L; //other fields get/set method //public void setSalary(double salary) { //this.salary = salary; //} private String name; private final double salary; private Date hireDay; private String department; @Override public Member clone() throws CloneNotSupportedException { Member m = (Member) super.clone(); m.hireDay = (Date) hireDay.clone(); return m; } @Override public boolean equals(Object o) { if( o==null || getClass()!=o.getClass()){ return false; } return fieldEquals(o); } private boolean fieldEquals(Object o){ Member m = (Member)o; return name==null ? false : name.equals(m.getName()) && 0==Double.compare(salary, m.getSalary()) && hireDay==null ? false : hireDay.getTime() == m.getHireDay().getTime() && department==null ? false : department.equals(m.getDepartment()); } //salary is fianl, must give it value when construct! //public Member() { //} public Member(String name ,double salary ,int year ,int month ,int day){ this.name = name; this.salary = salary; GregorianCalendar calendar = new GregorianCalendar(year ,month-1 ,day); hireDay = calendar.getTime(); } public Member(String name,double salary, int year ,int month ,int day ,String depart){ this.name = name; this.salary = salary; GregorianCalendar calendar = new GregorianCalendar(year ,month-1 ,day); hireDay = calendar.getTime(); department = depart; } public String toString(){ return "{" + "[$name="+name+ "]" + ",[$salary=" + salary + "]" + ",[$hireDay=" + hireDay+"]" + ",[$department="+ department + "]" + "}"; } @Override public int compareTo(Member member) { if (getClass() != member.getClass()) throw new ClassCastException(); if(salary < member.salary)return -1; if(salary > member.salary)return 1; return 0; } }
要正确实现某个类的 clone 方法
1、父类的 clone 方法必须都正确实现
2、类的对象域还不能声明为 final
可见 clone 方法的限制还是蛮多的,可以自定义copy 的方法:copy constructor 或 copy factory
//copy constructor public Member( Member member ){ this.name = member.getName(); this.salary = member.getSalary(); this.hireDay = new Date( member.getHireDay().getTime() ); this.department = member.getDepartment(); }
//copy factory public static Member copy( Member member ){ return new Member( member ); }
4、Comparable 的 compareTo 方法
注意:子类继承父类的 compareTo 方法时,要保存比较的对称性!
因而加了一个判断,是否为同一 Class !
class ExtendMember extends Member{ private static final long serialVersionUID = -2054912134719304214L; private Member secretary; private double donus; //get/set methods @Override public int compareTo(Member member) { if (getClass() != member.getClass()) throw new ClassCastException(); ExtendMember em = (ExtendMember) member; if(donus < em.donus)return -1; if(donus > em.donus)return 1; return 0; } @Override public ExtendMember clone() throws CloneNotSupportedException { ExtendMember em = (ExtendMember) super.clone(); em.setSecretary((Member)this.getSecretary().clone()); return em; } @Override public boolean equals(Object o) { if(!super.equals(o))return false; ExtendMember em = (ExtendMember) o; return secretary.equals(em.secretary); } public ExtendMember(String name ,double salary ,int year ,int month ,int day ,String department){ super(name ,salary ,year ,month ,day ,department); secretary = null; } //保持打印信息格式 public String toString(){ return removeLastString(super.toString()) + ",[secretary=" + secretary +"]}"; } protected String removeLastString( String str ){ if( str == null ){ return null; } return str.substring(0, str.length()-1); } }compareTo 方法与 equals 方法一致,即:(x.compareTo(y)==0) == (x.equals(y)),强烈推荐!
compareTo 方法与 equals 方法不一致,即:(x.compareTo(y)==0) != (x.equals(y))
示例如下:
public class ComparableVSEqeal {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
System.out.println("bd1 equals bd2: " + bd1.equals(bd2));
Set<BigDecimal> set = new HashSet<BigDecimal>();
set.add(bd1);
set.add(bd2);
CollectionPrintHelper.printCollection(set);
System.out.println("-------------------");
System.out.println("bd1 compareTo bd2: " + bd1.compareTo(bd2));
set = new TreeSet<BigDecimal>(set);
CollectionPrintHelper.printCollection(set);
}
}输出结果:
bd1 equals bd2: false
[0]:1.0
[1]:1.00
-------------------
bd1 compareTo bd2: 0
[0]:1.0
排序时有多个项:
public int compareTo(PhoneNumber pn) {
// Compare area codes
if (areaCode < pn.areaCode)return -1;
if (areaCode > pn.areaCode)return 1;
// Area codes are equal, compare prefixes
if (prefix < pn.prefix)return -1;
if (prefix > pn.prefix)return 1;
// Area codes and prefixes are equal, compare line numbers
if (lineNumber < pn.lineNumber)return -1;
if (lineNumber > pn.lineNumber)return 1;
return 0; // All fields are equal
}
相关文章推荐
- java对象通用方法之覆盖equals时请遵守通用约定、覆盖equals时总要覆盖hashCode、始终要覆盖toString、考虑实现Comparable接口
- 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解
- 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解(转载)
- JAVA源码分析之---Object类(二)---hashCode,equals,clone方法的使用
- Object 开发中常用的重写方法总结toString,equals,hashCode,compareTo
- 接口、Object类(toString(), equals(), hashCode())
- 为什么SpringAOP使用JDK动态代理时好像没有代理Object.[equals()、hashCode()、toString()]这三个方法
- Java记录 -57- Object的equals、hashcode和toString方法
- Object常用方法介绍及注意事项equals(),hashCode(),getClass(),toString()
- 复写Object超类的equals,hashCode,toString方法
- Object 开发中常用的重写方法总结toString,equals,hashCode,compareTo
- 《Java核心技术》第10版读书笔记之Chap5(3)——Object类及其equals、hashCode与toString方法
- 重写equals()与hashcode()方法,及comparable接口的实现
- Java记录 -57- Object的equals、hashcode和toString方法
- JAVA Object对象(toString、equals、hashCode方法)、String类、StringBuffer、StringBuider、System、Runtime、Date、Mat
- Object(equals,finalize,clone,hashCode,toString),与包的重名
- Object类之toString方法和equals方法
- Effective Java(覆盖equals时总要覆盖hashcode方法、始终要覆盖toString)
- equals、hashCode和clone方法
- 关于Object类的equals方法和hashCode方法