gpt4 book ai didi

java - 从参数分配集合的首选方法是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:37:58 26 4
gpt4 key购买 nike

我有这门课:

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

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

  • 忽略它?
  • 克隆集合?
  • ...?

编辑:为了阐明为什么这是不好的,想象一下:

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

仅存储引用构成了一种将数据注入(inject)私有(private)字段 myObject.data 的方法,尽管它应该是完全私有(private)的。

根据 MyClass 的性质,这可能会产生严重影响。

最佳答案

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

下一个最佳方法是“写时复制”克隆。 Java 运行时不支持此功能。

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

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

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

另一种解决方案是,一旦将它们存储在某处,就始终使它们不可变:

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

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

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

这里的想法是尽快将集合变成“值对象”。任何想要更改集合的人都必须复制它,更改它,然后再将其保存回来。

在一个类中,您可以保持集合可变并将其包装在 getter 中(无论如何您都应该这样做)。

这种方法的问题:性能(但它可能没有您预期的那么糟糕)和纪律(如果您在某处忘记了它就会中断)。

关于java - 从参数分配集合的首选方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2369693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com