【问题标题】:How to create a copy of object of class with map?如何使用地图创建类对象的副本?
【发布时间】:2016-03-20 04:37:04
【问题描述】:

我有课

public class student 
{
  private int Id;
  private map<String , String> subjects;
  private map<String , String> teachers;
  private String name; 
}

让我更清楚地解释一下这个场景。我有一个将 Student 对象作为参数的函数。正在从各种其他类调用此函数。现在在这个函数中,我创建了七个线程来根据学生输入对象执行一些计算。虽然目前还没有修改学生对象。我仍然想通过传入学生对象的副本来保证它的安全,这样如果以后有人修改任何线程中的输入,它就不应该修改其他线程。

那么我怎样才能为地图创建一个新对象呢? 我可以尝试的另一种解决方案是将此类创建为不可变的,但即便如此,地图也是一个问题。 如何使地图不可变。

【问题讨论】:

  • 如果一个线程修改了一张地图,以后需要对所有的副本进行协调吗?这是一个难题。
  • 你可以只从 getter 方法返回地图的副本吗? new HashMap()。哦,您希望线程能够修改Student 实例?这将影响所有其他线程。
  • 要求似乎不清楚。您是否希望这些线程修改对象?如果您可以以一种使对象不可变的方式解决您的问题,这是最简单和最直接的方法,那么我不明白为什么“地图是一个问题”。也许Java: how to make a private field Map immutable within a class? 是相关的?
  • 为什么会有 7 个线程同时操作同一个学生?如果您使学生对象不可变,那么这些线程中的每一个都会有自己的副本(他们无法修改);这有什么帮助?您能否添加更多代码来解释更大的图景?
  • 请使用此信息编辑问题,并为您的函数添加代码。在任何情况下,如果变量已被声明为普通的Map,则没有人可以/不应该假设元素排序。接口契约没有定义元素的排序方式。

标签: java multithreading dictionary clone immutability


【解决方案1】:

如果线程必须操作对象:

  • 创建对象和地图的副本,例如使用Map&lt;String, String&gt; subjects = new HashMap&lt;&gt;()
  • 如果您的对象变得越来越复杂,请使用复制库(如推土机)或使用序列化(如 jaxb)

如果线程不必操作对象:

  • 只需将同一个实例传递给所有线程
  • 为了安全起见,您可以使用 Collections 类中的方法使地图不可变

顺便说一句:

  • 考虑存储Subject 对象和Teacher 对象的列表。这使您的代码比使用地图更容易扩展。

【讨论】:

  • 我不能像这样复制 Map subject = new HashMap() 。您不知道地图可能已被初始化为树形图,或者可能是链接的哈希图。这是我最关心的问题。
  • 另外,在第二种情况下,您是说如果我不必进行操作,我可以使用收集方法使地图不可变,您能详细解释一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
  • 2020-03-03
  • 1970-01-01
  • 2011-06-15
相关资源
最近更新 更多