1、equals 方法和hashCode 方法实现示例:
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方法@Overridepublic 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}@Overridepublic 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 对象*/@Overridepublic boolean equals(Object object) {return super.equals(object) &&extendName == null ? false : ((ExtendEqualHashCode)object).getExtendName().equals(extendName);}@Overridepublic 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 方法@Overridepublic 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;}@Overridepublic 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);}@Overridepublic 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 arraypublic 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 Collectionpublic 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 Mappublic 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;@Overridepublic Member clone() throws CloneNotSupportedException {Member m = (Member) super.clone();m.hireDay = (Date) hireDay.clone();return m;}@Overridepublic 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 + "]" +"}";}@Overridepublic 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 constructorpublic Member( Member member ){this.name = member.getName();this.salary = member.getSalary();this.hireDay = new Date( member.getHireDay().getTime() );this.department = member.getDepartment();}
//copy factorypublic 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@Overridepublic 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;}@Overridepublic ExtendMember clone() throws CloneNotSupportedException {ExtendMember em = (ExtendMember) super.clone();em.setSecretary((Member)this.getSecretary().clone());return em;}@Overridepublic 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 codesif (areaCode < pn.areaCode)return -1;if (areaCode > pn.areaCode)return 1;// Area codes are equal, compare prefixesif (prefix < pn.prefix)return -1;if (prefix > pn.prefix)return 1;// Area codes and prefixes are equal, compare line numbersif (lineNumber < pn.lineNumber)return -1;if (lineNumber > pn.lineNumber)return 1;return 0; // All fields are equal
}