ArrayList,Java。这两个构造函数有什么区别?

5
我还是Java的新手,您能告诉我这两个构造函数的区别吗?
第一个:
public class Plan
{

   ArrayList<Point2D> points;

   public Plan(ArrayList<Ponto2D> points)
   {
       this.points = new Arraylist<Point2D>(points);
   }

}

和这个: 第二个:

public class Plan
{

    public Plan(ArrayList<Point2D> lpoints)
    {
        points = new ArrayList<Point2D>();
        for(Point2D p : lpoints) point.add(p.clone());
    }

}

2
请注意缩进,你的代码真的很难读。 - realUser404
1
第一个构造函数接受一个集合并将其分配给“points” ArrayList,第二个构造函数接受一个ArrayList,在初始化“points”后遍历它,并添加到“points”中。 - Honinbo Shusaku
1
@Abdul,第一个并没有将传递的列表赋值,它只是复制了该列表。 - Mick Mnemonic
2
@Abdul 还要注意第二个示例中使用了 Point2D.clone() - Edd
@MickMnemonic 哦,好的,我刚查了一下,学到了什么是“浅拷贝”。 - Honinbo Shusaku
4个回答

5
第一个构造函数是 浅拷贝,第二个构造函数是 深拷贝
答案由 S.Lott这个问题中给出。

浅拷贝尽可能地少复制。 集合的浅拷贝是集合结构的副本,而不是元素的副本。 通过浅拷贝,两个集合现在共享各自的元素。

深拷贝复制所有内容。 集合的深拷贝是原始集合中所有元素都被复制的两个集合。


我相信第一个构造函数实际上是在克隆列表,因此不共享元素。 - realUser404
@realUser404 这是一个陷阱!(:P) 第一个构造函数克隆了列表,但共享相同的元素,第二个构造函数则通过clone()复制元素。您可以查看ArrayListOpenJDK实现,它在幕后使用System.arraycopy(...) - NiziL

3
this.points = new Arraylist<Point2D>(points);

这段代码需要一整个集合,并使用该集合初始化你的points ArrayList。

for(Point2D p : lpoints) point.add(p.clone());

这样做的结果是相同的,但是它会逐个将lpoints集合中的每个元素添加到您的points列表中。

因此,在您的使用情况下,使用第一种可能性。


在第二种情况下,它添加了 point2D 的一个 副本,这并不完全相同。 - Steve Marion

1
在您的第一个构造函数中,您使用了默认的Java构造函数来创建一个ArrayList,该构造函数将集合作为其参数。

(来自Java文档)

public ArrayList(Collection < ? extends E > c)

构造一个包含指定集合元素的列表,按照它们被集合的迭代器返回的顺序排列。

这与编写自己的迭代器基本相同(来自您的示例)。

public Plan(ArrayList<Point2D> lpoints) {
  points = new ArrayList<Point2D>();
  for(Point2D p : lpoints) 
      point.add(p.clone());
}

在这个例子中,我们使用了一个叫做 .clone() 的方法,因为我们不想要每个对象的浅层拷贝,而是想要复制它们。
[编辑]: 这两个例子并不做同样的事情。第一个是浅拷贝,第二个是深拷贝。

1
在第一种情况下,参数ArrayList共享相同的点(p1.equals(p2)为true,p1 == p2为true);在第二种情况下,它们具有不同的点副本(p1.equals(p2)为true,但p1 == p2为false)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接