【问题标题】:Java deep clone an objectJava 深度克隆一个对象
【发布时间】:2014-12-20 07:20:39
【问题描述】:

我在将对象复制到新对象时遇到了一些麻烦。

最初我尝试过这个:

State clonedState = state;

但后来我注意到我在“cloneState”中所做的更改也会影响“状态”。

然后我去搜索,发现了深度克隆。 有些人建议使用库,有些人建议先序列化,然后再反序列化。

如果没有这些,有没有办法做到这一点?

我也试过了,结果一样:

    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;
}

进一步阅读后,我尝试使用序列化和反序列化。 所以我在我的构造函数类中添加了这个方法:

    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;
}

在主类中,我添加了这个:

State clonedState = state.deepCopy();

不知何故,结果是一样的……我修改了“clonedState”,“state”也在修改中。

非常感谢任何帮助!

编辑:

作为参考,这里是它发生的方法:

    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++;
        }
    }
}

这是输出:

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)

【问题讨论】:

    标签: java object serialization deep-copy


    【解决方案1】:

    在您的 deepcopy 方法中,您再次使用数组和对象。因此, state 和 clonedState 再次引用了同一个对象。如果你不想做序列化和反序列化,那么你需要为每个对象创建新对象并复制原始类型。

    而不是:-

     Piece pieceDetail = state.getPieceDetail();
    

    你需要做的:-

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

    如果有任何对象仅在pieceDetail 内,则您需要重复执行此操作。

    了解更多详情。你可以通过Java: recommended solution for deep cloning/copying an instance

    【讨论】:

    • 谢谢,现在知道了!所以数组,矩阵,对象,不能被复制,它们需要被克隆......嗯......到目前为止,Java 看起来如此完美,现在它不再...... xD 非常感谢 :)
    猜你喜欢
    • 2013-10-11
    • 2012-06-26
    • 1970-01-01
    • 2010-09-09
    • 2012-06-05
    • 1970-01-01
    • 2017-02-23
    相关资源
    最近更新 更多