假设您要将x个对象添加到集合中,并在将它们添加到集合之后或之前修改对象属性。什么时候在修改对象之前或之后将元素添加到集合中。
选项A)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
objects.add(newObject);
newObject.setMyAttr("ok");
}
选项B)
public static void addToCollection(List<MyObject> objects) {
MyObject newObject = new MyObject();
newObject.setMyAttr("ok");
objects.add(newObject);
}
答案 0 :(得分:12)
为了安全起见,您应该在添加之前进行修改,除非有特殊原因您无法执行此操作,并且您知道该集合可以处理修改。可以合理地假设该示例是安全的,因为一般List
契约不依赖于对象属性 - 但是没有说明具体实现,这可能具有取决于对象值的其他行为。
TreeSet和Maps通常不会容忍在插入对象后修改对象,因为集合的结构取决于对象的属性。对于树,一旦添加了项目,比较器使用的任何属性都无法更改。对于地图,它必须保持不变的hashCode。
因此,一般来说,首先修改,然后添加。这对于并发集合来说变得更加重要,因为首先添加可以导致其他集合用户在为对象分配最终状态之前看到对象。
答案 1 :(得分:4)
您提供的示例不会有任何问题,因为您使用的是不关心对象内容的List集合。
如果您使用的是类似TreeMap的内容,它会对其存储的Object键的内容进行排序,这可能会导致Collection进入意外状态。同样,这取决于equals方法是否使用您要更改的属性进行比较。
最安全的方法是在将对象放入集合之前修改它。
答案 2 :(得分:1)
要遵循的一个好的设计规则,不是将半构造的对象暴露给第三方子系统。
因此,根据此规则,将您的对象初始化为最佳能力,然后将其添加到列表中。
如果objects
是ArrayList
,则最终结果可能相同,但如果objects
是List
的特殊风格,会触发某种通知事件每次添加一个新对象时,顺序都会非常重要。
答案 3 :(得分:0)
在我看来,它依赖于已设置的属性和集合的tyle,如果集合是一个集合,并且该属性在方法上具有相同的或者hascode,那么我肯定会在此之前设置此属性,也可以参考sorterd list等。在其他情况下,这是无关紧要的。但是对于创建对象的这个例子,我将首先设置属性而不是添加到集合,因为代码组织得更好。
答案 4 :(得分:0)
我认为无论哪种方式都一样,我个人喜欢B,:))
答案 5 :(得分:0)
确实可以归结为情况需要。功能上没有区别。
您应该注意的一件事是确保您拥有要修改的对象的正确句柄。
答案 6 :(得分:0)
当然,在这种情况下,修改对象是“创建对象”思想的一部分,因此应该与构造函数一起分组。在“创建对象”之后,“将其添加到集合中”。因此,我会做B,甚至可能在修改后添加一个空行,以便更加强调两个不同的想法。