您的位置:首页 > 移动开发 > Objective-C

Object的方法equals,hashCode,toString,clone。另外Comparable接口的方法

2011-08-12 11:39 633 查看
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方法

@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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐