简体   繁体   English

Java-等于和哈希码

[英]Java - equals and hashcode

I am thinking of using a Set of BusinessObjects in Java. 我正在考虑在Java中使用一Set BusinessObjects。 My intention is, that in each set there should be only ONE instance of each business object, but one business object can be shared across many sets. 我的意图是,每个集合中每个业务对象应该只有一个实例,但是一个业务对象可以在许多集合中共享。 So, as an example: 因此,例如:

BO1 - instance of BusinessObject1
BO11 - instance of BusinessObject1
BO2 - instance of BusinessObject2

this is correct 这是对的

[BO1, BO2] or [BO1] [BO1,BO2]或[BO1]

but this isn't [BO1, BO11] 但这不是[BO1,BO11]

Since I wanted to make sure this is enforced, I was thinking of specifying an AbstractBusinessObject like this: 由于我想确保这是强制性的,因此我在考虑指定这样的AbstractBusinessObject:

public abstract class AbstractBusinessObject {

    @Override
    public int hashCode() {
        return this.getClass().getName().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null)
            return this.getClass() == obj.getClass();
        return false;
    }
}

Do you think that is a good idea? 您认为这是个好主意吗?

Why not simply use Enums? 为什么不简单地使用Enums? You can use Enum of business objects and EnumSet of Business Objects. 您可以使用业务对象的Enum和业务对象的EnumSet

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY;
    static final EnumSet<Day> weekend = EnumSet.of(SATURDAY,SUNDAY);
}

Tutorial here 教程在这里

Now if your business object are not designed for above purpose then just implement equals and hashcode in a normal way. 现在,如果您的业务对象不是为上述目的而设计的,则只需以常规方式实现equals和hashcode。 HashSet add method will anyway ignore duplicates. HashSet的add方法将始终忽略重复项。

This link discusses about equals and hashcode contract. 链接讨论了关于等号和哈希码契约。

For Business objects general rule is equals and hashcode needs to be implemented using your business object PK. 对于业务对象,一般规则是相等的,并且需要使用您的业务对象PK来实现哈希码。

Like For Employee object employee number can be considered as business key and pk can be different so equals and hashcode should based on employee number. 像For Employee对象一样,可以将员工编号视为业务密钥,而pk可以不同,因此等于和哈希码应基于员工编号。

No, this is a bad idea. 不,这是一个坏主意。 This does not actually prevent different sections of your code from doing 这实际上并不能阻止代码的不同部分执行

BusinessObject bo1 = new BusinessObject();
bo1.setId(1);
bo1.setName("foo");

BusinessObject bo1copy = new BusinessObject();
bo1copy.setId(1);
bo1copy.setName("bar");

And thus having two copies of the same "business object" with different field values. 因此,具有不同字段值的同一“业务对象”的两个副本。

Your equals() implementation would also treat all instances of BusinessObject as having the same value ( bo1.equals(bo1copy) == true in the above code), which will mess up using it in any sort of collection. 您的equals()实现还会将BusinessObject所有实例都视为具有相同的值(以上代码中的bo1.equals(bo1copy) == true ),这将在任何类型的集合中使用它。

If you need to control the number of instances of a certain type instantiated in your program, then simply only instantiate one instance of the object. 如果您需要控制程序中实例化的某种类型的实例的数量,则只需实例化该对象的一个​​实例即可。

Throw all business objects into a HashSet. 将所有业务对象都放入HashSet中。 You cannot have duplicates in a HashSet (by the equals method), so if you throw B1, B11 and B2 into a HashSet, it will contain B1 and B2. HashSet中不能有重复项(通过equals方法),因此,如果将B1,B11和B2放入HashSet中,它将包含B1和B2。

You should override the equals and hashCode methods in the BusinessObject to work with those attributes that make a BusinessObject unique. 您应该重写BusinessObject中的equals和hashCode方法,以使用那些使BusinessObject唯一的属性。

If for some reason you can't follow AmitD's advice and use Enums, then instead of Sets you could use Maps keyed on a marker interface. 如果由于某种原因您不能遵循AmitD的建议而使用枚举,则可以使用在标记界面上键入键的Maps来代替Sets。

I have no idea what problem this would be solving, but... 我不知道这将解决什么问题,但是...

  1. Create a new Marker interface 创建一个新的Marker界面
  2. Have each of your Business Object classes implement it 让您的每个业务对象类都实现它
  3. In each place where you want a collection as you've described it, use 在您想要收集的每个地方,使用

     Map<Class<? extends Marker>, Marker> soloBOMap = // whatever concrete map; soloBOMap.put(bo.getClass(), bo); 

It's weird; 有点奇怪; of that I'm sure. 我敢肯定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM