0

I am having some troubles of copying an object to a new object.

Initially I tried this:

State clonedState = state;

But then I noticed that the changes I make in "clonedState" affects "state" as well.

So then I went to search, and found out about deep cloning. Some people suggested using libraries, others to serialize, then deserialize.

Is there no way of doing this without any of these?

I also tried this, with the same results:

    public static State cloneState(State state){
        int[][] currentBoard = state.getCurrentBoard();
        int[] currentPieces = state.getCurrentPieces();
        int totalPoints = state.getTotalPoints();
        Piece pieceDetail = state.getPieceDetail();
        int acquiredPoints = state.getAcquiredPoints();
        int[] initialList = state.getInitialList();
        int[][] initialBoard = state.getInitialBoard();
        int parentStateID = state.getParentStateID();
        int stateID = state.getStateID();
        State clone = new State(parentStateID, 
            stateID, 
            currentBoard, 
            currentPieces, 
            totalPoints, 
            acquiredPoints, 
            initialList, 
            initialBoard, 
            pieceDetail);
    return clone;
}

After further reading, I tried using serialization and de-serialization. So I added this method in my constructor class:

    public State deepCopy() throws Exception{
    //Serialization of object
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(this);

    //De-serialization of object
    ByteArrayInputStream bis = new   ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream in = new ObjectInputStream(bis);
    State clone = (State) in.readObject();
    return clone;
}

And in the main class, I added this:

State clonedState = state.deepCopy();

Somehow, the results are the same... I modify "clonedState", and "state" is being modified as well.

I greatly appreciate any help!

Edit:

For reference, here is the method where it happens:

    public static void operateGreen(State state) throws Exception{
    if(getNextPiece(state) == 1){ //Se a proxima peca a colorcar for um +
        int pos = 0;
        System.out.println("pieces in state: " + countPiecesList(state));
        while (pos <= 24){//percorrer o tabuleiro
            System.out.println("Position: " + pos);
            State clonedState = state.deepCopy();
            System.out.println("pieces in state: " + countPiecesList(state));
            System.out.println("pieces in clonedState: " + countPiecesList(clonedState));
            if (checkPosPiece(state, pos, -1) == true){ //se o campo estiver vazio
                removePieceFromList(clonedState);
                int points = 0;
                nodes++;
                modifyBoard(clonedState, pos, 1); //atualiza o tabuleiro
                Piece pieceDetail = new Piece(1, pos); //cria nova jogada
                //Verifica se fez figura
                int tempPos = 6;
                boolean figureFound = false;
                while (tempPos <= 18 && figureFound == false){ //pesquisar se tem algum centro de figura + entre os campos 6 e 18
                    if (checkGreen(clonedState,tempPos)) figureFound = true;
                    tempPos++;
                }
                if (figureFound){
                    points = acquiredPoints(armLength(clonedState, tempPos, 0, 1, 1)*4+1); //calcula o tamanho da figura, para devolver os pontos obtidos
                    clearGreen(clonedState, tempPos);
                }

                setPieceToState(clonedState, pieceDetail);
                setTotalPointsOfState(clonedState, points);
                setStateID(clonedState);
                setParentStateID(state, clonedState);
                addState(clonedState);
            }
            pos++;
        }
    }
}

And here is the output:

pieces in state: 4
Position: 0
pieces in state: 4
pieces in clonedState: 4
Position: 1
pieces in state: 3
pieces in clonedState: 3
Position: 2
pieces in state: 2
pieces in clonedState: 2
Position: 3
pieces in state: 1
pieces in clonedState: 1
Position: 4
pieces in state: 0
pieces in clonedState: 0
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at MainPC.removePieceFromList(MainPC.java:223)
    at MainPC.operateGreen(MainPC.java:778)
    at MainPC.setProblem(MainPC.java:945)
    at MainPC.main(MainPC.java:43)
Machavity
  • 30,841
  • 27
  • 92
  • 100
Wilhelm Sorban
  • 1,012
  • 1
  • 17
  • 37

1 Answers1

1

Inside you deepcopy method you are again using arrays and objects. So, state and clonedState is again referencin same object. If you don't want to do serailiaze and desearialze ,then you need to create new object for each object and copy the primitive type.

Instead of :-

 Piece pieceDetail = state.getPieceDetail();

You need to do :-

Piece pieceDetail = new pieceDetail();
peiceDetail.setField1(state.getPieceDetail().getfield1);

This you need to do recusively, if any object is inside pieceDetail only.

For more detail. you may go through Java: recommended solution for deep cloning/copying an instance

Community
  • 1
  • 1
Panther
  • 3,312
  • 9
  • 27
  • 50
  • Thank you, got it now! So arrays, matrixes, objects, can't be copied, they need to be cloned... bah... Java seemed so perfect so far, now it doesn't anymore... xD Thanks a lot :) – Wilhelm Sorban Dec 20 '14 at 08:00