从参数中分配集合的首选方法是什么? [英] What's the preferred way to assign a collection from a parameter?

查看:134
本文介绍了从参数中分配集合的首选方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个课程:

public MyClass {
    public void initialize(Collection<String> data) {
        this.data = data; // <-- Bad!
    }
    private Collection<String> data;
}

这显然是糟糕的风格,因为我引入了一个共享的可变状态。处理此问题的首选方法是什么?

This is obviously bad style, because I'm introducing a shared mutable state. What's the preferred way to handle this?


  • 忽略它?

  • 克隆集合?

  • ...?

编辑:澄清为什么这是不好,想象一下:

To clarify why this is bad, imagine this:

MyClass myObject = new MyClass();
List<String> data = new ArrayList<String>();
myObject.initialize(data); // myObject.data.size() == 0
data.add("Test"); // myObject.data.size() == 1 

只需存储引用就可以实现注入数据进入私有字段 myObject.data ,虽然它应该是完全私有的。

Just storing the reference poses a way to inject data into the private field myObject.data, although it should be completely private.

取决于<的性质code> MyClass 这可能会产生严重影响。

Depending on the nature of MyClass this could have serious impacts.

推荐答案

最好的办法是深入克隆参数。出于性能原因,这通常是不可能的。最重要的是,并非所有对象都可以被克隆,因此深度复制可能会引发异常并导致各种头痛。

The best way is to deep clone the parameter. For performance reasons, this is usually not possible. On top of that, not all objects can be cloned, so deep copying might throw exceptions and cause all kinds of headache.

下一个最好的方法是复制 - 在写克隆。在Java运行时中没有对此的支持。

The next best way would be a "copy-on-write" clone. There is no support for this in the Java runtime.

如果您认为有人可能会改变集合,请使用复制构造函数执行浅表复制:

If you think that it's possible someone mutates the collection, do a shallow copy using the copy constructor:

this.data = new HashSet<String> (data);

这将解决您的问题(因为String是不可变的)但是当集合中的类型时它会失败是可变的。

This will solve your problem (since String is immutable) but it will fail when the type in the set is mutable.

另一种解决方案是在将它们存储到某处时始终使这些集成为不可变的:

Another solution is to always make the sets immutable as soon as you store them somewhere:

Set<String> set = ...
...build the set...

// Freeze the set
set = Collections.unmodifiableSet(set);

// Now you can safely pass it elsewhere
obj.setData (set);

这里的想法是尽快将收集转化为价值对象。任何想要更改集合的人都必须复制它,更改它然后再保存。

The idea here is turn collections into "value objects" as soon as possible. Anyone who wants to change the collection must copy it, change it and then save it back.

在一个类中,你可以保持set的可变性并将其包装在getter中(你应该这样做)。

Within a class, you can keep the set mutable and wrap it in the getter (which you should do anyway).

这种方法的问题:表现(但可能没有你想象的那么糟糕)和纪律(如果你忘了它就会​​中断)。

Problems with this approach: Performance (but it's probably not as bad as you'd expect) and discipline (breaks if you forget it somewhere).

这篇关于从参数中分配集合的首选方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆