论坛首页 Java企业应用论坛

实现实体的hashCode,equals时候请注意

浏览 46702 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-11-18  
多对多双向关系,如果hashCode和equals正常写之,将出现load不上的问题。

详情请看
http://www.erproad.org/showlog.asp?cat_id=30&log_id=371
   发表时间:2004-11-18  
用得着这么复杂吗?比较一下id不就得了。
public abstract class EntityBase{
  private Long id;
  public Long getId();{
    return id;
  }
  //setter...

  public boolean equals(Object o);{
    if(this==o); return true;
    if(o==null); return false;
    if(this.id==null); return false;
    if(getClass!=o.getClass();); return false;
    EntityBase e=(EntityBase);o;
    if(e.id==null); return false;
    return id.equals(e.id);;
  }
  
  public int hashCode();{
    return id==null?super.hashCode();:id.hashCode();;
  }
}
0 请登录后投票
   发表时间:2004-11-19  
比较一下ID就行了吗?

   呵呵,我是不会这样写的。 至于原因,你都想当然了,我也不说了。
0 请登录后投票
   发表时间:2004-11-19  
id是不可靠的
如果一个transient po ,id==null
but business value equals existed po,

..........
0 请登录后投票
   发表时间:2004-11-19  
winhello,please copy the formatted java source to here .thanks
0 请登录后投票
   发表时间:2004-11-19  
zingers 写道
id是不可靠的
如果一个transient po ,id==null
but business value equals existed po,
..........


一个transient object和一个persistent object, 哪怕它们的business value都相同, 偶还是认为它们是不同的

比较ID有什么说不过去的地方呢?偶N个实际项目中就是这样用的......
0 请登录后投票
   发表时间:2004-11-19  
比较ID不是太好的方法(当然也是可以)。因为新建PO的时候ID一般都为空或者0.

一般都是用业务字段来比较(复合的业务字段等),例如:像XXXname,或者其它的呀。

不过觉得equals与hashCode并没有很大什么,因为平时我们只是用Set,List,Map等,其实很少有记录重复的。有时我们必须允许重复。

现说PO就是一种数据对象(大部时候只有set/get方法),标识它唯一的是它的ID(或者复合ID)(大部分情况下)。

所以我觉得equals与hashCode并没有多大重要性,甚至可以不override。
0 请登录后投票
   发表时间:2004-11-19  
/*
 * 作成日: 2004-11-19
 *
 * この生成されたコメントの挿入されるテンプレートを変更するため
 * ウィンドウ > 設定 > Java > コード生成 > コードとコメント
 */

import java.io.Serializable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
/**
 * @author Administrator
 *
 * この生成されたコメントの挿入されるテンプレートを変更するため
 * ウィンドウ > 設定 > Java > コード生成 > コードとコメント
 */
public class BasePersistentObject implements Serializable {

	public String toString(); {
		return ToStringBuilder.reflectionToString(
			this,
			ToStringStyle.MULTI_LINE_STYLE);;
	}

	public boolean equals(Object o); {
		if (this == o); {
			return true;
		}
		if (o == null); {
			return false;
		}

		Class lhsClass = getClass();;
		Class rhsClass = o.getClass();;
		Class testClass;

		if (lhsClass.isInstance(o);); {
			testClass = lhsClass;
			if (!rhsClass.isInstance(this);); {

				testClass = rhsClass;

			}

		} else if (rhsClass.isInstance(this);); {
			testClass = rhsClass;
			if (!lhsClass.isInstance(o);); {

				testClass = lhsClass;

			}
		} else {
			return false;
		}

		EqualsBuilder equalsBuilder = new EqualsBuilder();;
		try {
			equalsReflectionAppend(o, testClass, equalsBuilder);;
			while (testClass.getSuperclass(); != null
				&& !testClass.getSuperclass();.equals(Object.class);); {
				testClass = testClass.getSuperclass();;
				equalsReflectionAppend(o, testClass, equalsBuilder);;
			}
		} catch (IllegalArgumentException e); {

			return false;
		}
		return equalsBuilder.isEquals();;
	}

	private void equalsReflectionAppend(
		Object rhs,
		Class clazz,
		EqualsBuilder builder); {
		Field[] fields = clazz.getDeclaredFields();;
		AccessibleObject.setAccessible(fields, true);;
		for (int i = 0; i < fields.length && builder.isEquals();; i++); {
			Field f = fields[i];
			if ((f.getName();.indexOf('$'); == -1);
				&& (!Modifier.isTransient(f.getModifiers();););
				&& (!Modifier.isStatic(f.getModifiers();););); {
				try {
					if (Collection.class.isAssignableFrom(f.getType(););); {
						builder.append(
							f.get(this);.getClass();,
							f.get(rhs);.getClass(););;
					} else {
						builder.append(f.get(this);, f.get(rhs););;
					}
				} catch (IllegalAccessException e); {
					//this can't happen. Would get a Security exception instead
					//throw a runtime exception in case the impossible happens. 
					throw new InternalError("Unexpected IllegalAccessException");;
				}
			}
		}
	}

	public int hashCode(); {
		HashCodeBuilder builder = new HashCodeBuilder(17, 37);;
		Class clazz = getClass();;
		hashCodeReflectionAppend(clazz, builder);;
		while (clazz.getSuperclass(); != null
			&& clazz.getSuperclass();.equals(Object.class);); {
			clazz = clazz.getSuperclass();;
			hashCodeReflectionAppend(clazz, builder);;
		}
		return builder.toHashCode();;
	}
	private void hashCodeReflectionAppend(
		Class clazz,
		HashCodeBuilder builder); {
		Field[] fields = clazz.getDeclaredFields();;
		AccessibleObject.setAccessible(fields, true);;
		for (int i = 0; i < fields.length; i++); {
			Field f = fields[i];
			if ((f.getName();.indexOf('$'); == -1);
				&& (!Modifier.isTransient(f.getModifiers();););
				&& (!Modifier.isStatic(f.getModifiers();););); {
				try {
					if (Collection.class.isAssignableFrom(f.getType(););); {
						builder.append(f.get(this);.getClass(););;
					} else {
						builder.append(f.get(this););;
					}
				} catch (IllegalAccessException e); {
					//this can't happen. Would get a Security exception instead 
					//throw a runtime exception in case the impossible happens. 
					throw new InternalError("Unexpected IllegalAccessException");;
				}
			}
		}
	}

}
0 请登录后投票
   发表时间:2004-11-19  
weihello 写道
比较一下ID就行了吗?

   呵呵,我是不会这样写的。 至于原因,你都想当然了,我也不说了。

嘿嘿,你也仔细想想吧
Readonly这回跟我比较一致呀
0 请登录后投票
   发表时间:2004-11-20  
CafeBabe 写道
weihello 写道
比较一下ID就行了吗?

   呵呵,我是不会这样写的。 至于原因,你都想当然了,我也不说了。

嘿嘿,你也仔细想想吧
Readonly这回跟我比较一致呀



   谁和你一致都无关,即使是上帝

  如果上帝是错的,我也会和他理论.

   即使上帝是对的,但未能说服我,那么我还会继续理论.

   搞技术总不能人云亦云, 是这样就是这样,不是这样就是这样.

   这儿不是官场.........
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics