OtagoHarbour
OtagoHarbour

Reputation: 4183

Cloned Vector Still Getting Overwritten

I am trying to make a copy of a vector of objects so that I can have a modified vector but keep the original vector in its original form. I use the following code.

    Vector<Triangle_dt> displayTriangles=(Vector)delaunayTriangles.clone();
    if (boundingBox.maxY()>=768){
        double scale=767.0/boundingBox.maxY();
        Triangle_dt newTriangle, oldTriangle;
        for (int i=0; i<delaunayTriangles.size(); ++i){
            newTriangle=displayTriangles.elementAt(i);
            oldTriangle=delaunayTriangles.elementAt(i);
            newTriangle.p1().setX(oldTriangle.p1().x()*scale);
            newTriangle.p1().setY(oldTriangle.p1().y()*scale);
            newTriangle.p2().setX(oldTriangle.p2().x()*scale);
            newTriangle.p2().setY(oldTriangle.p2().y()*scale);
            newTriangle.p3().setX(oldTriangle.p2().x()*scale);
            newTriangle.p3().setY(oldTriangle.p2().y()*scale);
        }
    }

The old vector is overwritten when I change the new vector. I thought the idea of .clone() was to copy a vector by value rather than by reference.

Edit: I tried modifying the code to do deep copying using serialization. The code follows.

  ObjectOutputStream oos = null;
  ObjectInputStream ois = null;
  try
  {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    oos = new ObjectOutputStream(bos);
    // serialize and pass the object
    oos.writeObject(delaunayTriangles);
    oos.flush();               
    ByteArrayInputStream bin = 
          new ByteArrayInputStream(bos.toByteArray()); 
    ois = new ObjectInputStream(bin);                  
    // return the new object
    Vector<Triangle_dt> displayTriangles = (Vector<Triangle_dt>)ois.readObject(); 
    if (boundingBox.maxY()>=768){
        double scale=767.0/boundingBox.maxY();
        Triangle_dt newTriangle, oldTriangle;
        for (int i=0; i<delaunayTriangles.size(); ++i){
            newTriangle=displayTriangles.elementAt(i);
            oldTriangle=delaunayTriangles.elementAt(i);
            newTriangle.p1().setX(oldTriangle.p1().x()*scale);
            newTriangle.p1().setY(oldTriangle.p1().y()*scale);
            newTriangle.p2().setX(oldTriangle.p2().x()*scale);
            newTriangle.p2().setY(oldTriangle.p2().y()*scale);
            newTriangle.p3().setX(oldTriangle.p2().x()*scale);
            newTriangle.p3().setY(oldTriangle.p2().y()*scale);
        }
    }
    return displayTriangles;
  }
  catch(Exception e)
  {
     System.out.println("Exception in ObjectCloner = " + e);
     throw(e);
  }
  finally
  {
     oos.close();
     ois.close();
  }

However the call

oos.writeObject(delaunayTriangles);

through an exception

e = (java.io.NotSerializableException) java.io.NotSerializableException: delaunay_triangulation.Triangle_dt

Upvotes: 0

Views: 57

Answers (3)

OtagoHarbour
OtagoHarbour

Reputation: 4183

I figured out a method that works.

static Triangle_dt CopyOfTriangle(Triangle_dt oldTriangle){
    Point_dt[] points=new Point_dt[3];

    try{
        points[0]=new Point_dt(oldTriangle.p1().x(), oldTriangle.p1().y());
        points[1]=new Point_dt(oldTriangle.p2().x(), oldTriangle.p2().y());
        points[2]=new Point_dt(oldTriangle.p3().x(), oldTriangle.p3().y());

        return new Triangle_dt(points[0], points[1], points[2]);
    }
    catch(Exception e){
        System.out.println("Exception in CopyOfTriangle = " + e);
        throw(e);
    }
}

static Vector<Triangle_dt> GetDelaunayTriangulationDisplayTriangles(Vector<Triangle_dt> delaunayTriangles,
            BoundingBox boundingBox){
    try{
        Vector<Triangle_dt> displayTriangles=new Vector<Triangle_dt>();
        if (boundingBox.maxY()>=768){
            double scale=767.0/boundingBox.maxY();
            Triangle_dt newTriangle, oldTriangle;
            for (int i=0; i<delaunayTriangles.size(); ++i){
                oldTriangle=delaunayTriangles.elementAt(i);
                if (oldTriangle.p3()!=null){
                    newTriangle=CopyOfTriangle(oldTriangle);
                    newTriangle.p1().setX(oldTriangle.p1().x()*scale);
                    newTriangle.p1().setY(oldTriangle.p1().y()*scale);
                    newTriangle.p2().setX(oldTriangle.p2().x()*scale);
                    newTriangle.p2().setY(oldTriangle.p2().y()*scale);
                    newTriangle.p3().setX(oldTriangle.p2().x()*scale);
                    newTriangle.p3().setY(oldTriangle.p2().y()*scale);
                    displayTriangles.add(newTriangle);
                }
            }
        }

        return displayTriangles;
    }
    catch(Exception e){
        System.out.println("Exception in GetDelaunayTriangulationDisplayTriangles = " + e);
        throw(e);
    }
}

Upvotes: 0

Rohit Jain
Rohit Jain

Reputation: 213223

The problem with using clone() method is that, it performs a shallow copy, and not a deep copy. So, even though the Vector instance if cloned, it doesn't clone the objects pointed to by the references inside it. It just copies the references.

The best way to perform deep copy is by using Serialization and Deserialization. Check out this article for some details, and sample implementation.

Upvotes: 3

benjamin.d
benjamin.d

Reputation: 2871

The clone method on Vector will prove a cloned list, but the elements inside will remain the same. You have to clone the elements as well.

Upvotes: 2

Related Questions