Tentando Copiar um objeto por valor, não por referência
8 respostas
M
mayconfsbrito
Olá amigos,
estou tentando copiar um objeto Rede para outro objeto do mesmo tipo e assim alterar os valores do segundo, só que consequentemente o valor do primeiro objeto também está sendo alterado como se os dois fossem um só. Segue abaixo um trecho do meu código (está gigante):
publicvoidverificaDesconexos(Reder,intraiz,Grafog)throwsException{intn=this.grafo.numVertices();intverifica=raiz;booleanaux=false;//Configura uma rede com algoritmo de Prim toda ativaRederedeTodaAtiva=newRede();redeTodaAtiva.setRedeSensores(r.getRedeSensores());redeTodaAtiva.getSensor(5).setAtivacao(true);r.getSensor(5).setAtivacao(false);System.out.println("TESTE "+" "+r.getSensor(5).isAtivacao());System.out.println("TESTE "+" "+redeTodaAtiva.getSensor(5).isAtivacao());
Na verdade você está copiando sim o valor, mas da referência!
Para fazer a cópia de um objeto, você tem que implementar o método clone da interface Cloneable.
publicclassMain{publicstaticvoidmain(String[]args){// cria uma pessoaPessoap1=newPessoa();p1.setNome("João");p1.setSobrenome("Silva");// "aponta" p2 para o endereço de p1Pessoap2=p1;// clona o objeto p1, apontando p3 para a nova Pessoa criadaPessoap3=(Pessoa)p1.clone();;// mostra todo mundoSystem.out.println(p1);System.out.println(p2);System.out.println(p3);// altera o sobrenome de p1 (vai refletir em p2, pq ambas as referencias// p1 e p2 apontam p/ o mesmo objetop1.setSobrenome("Sauro");// muda as propriedades de p3p3.setNome("Clone do João");p3.setSobrenome("da Silva");// p1 e p2 são iguais!System.out.println(p1);System.out.println(p2);// p3 não :DSystem.out.println(p3);}}
[]´s
M
mayconfsbrito
Fiz da forma que você me disse davidbuzatto, ficou conforme abaixo, porém nada, a impressão continuou a mesma coisa. O que será?
//Configura uma rede com algoritmo de Prim toda ativaRederedeTodaAtiva=(Rede)r.clone();redeTodaAtiva.getSensor(5).setAtivacao(true);r.getSensor(5).setAtivacao(false);System.out.println("TESTE r"+" "+r.getSensor(5).isAtivacao());System.out.println("TESTE rta"+" "+redeTodaAtiva.getSensor(5).isAtivacao());
Vc precisa clonar os sensores tbm!
Você precisa clonar tudo do objeto entendeu?
Se não, no final, mesmo que você tenha dois objetos “pai” diferentes, os componentes desses objetos vão ser os mesmos.
[]´s
M
mayconfsbrito
Os sensores não fazem parte do objeto Rede, segue abaixo a Classe Rede para ilustração.
Fiz os testes mas continua alterando o valor do objeto original.
importjava.util.ArrayList;publicclassRedeimplementsCloneable{privateArrayList<Sensor>redeSensores=newArrayList<Sensor>();privateint[][]matriz;publicRede(ArrayList<Sensor>redeSensores){this.redeSensores=redeSensores;}publicRede(){}publicvoidinicializaMatriz(){//inicializa matriz com o número de sensores(incluindo o sink)setMatriz(newint[this.redeSensores.size()][this.redeSensores.size()]);//preenche a matriz de adjacência utilizando a distância dos sensores de acordo com a área de comunicação de cada umfor(inti=0;i<this.redeSensores.size();i++){for(intj=0;j<this.redeSensores.size();j++){if(i==j||(!this.redeSensores.get(i).isAtivacao())||(!this.redeSensores.get(j).isAtivacao())){matriz[i][j]=0;}else{if(calculaDistancia(this.redeSensores.get(i),this.redeSensores.get(j))<=this.redeSensores.get(i).getComunicacao()){matriz[i][j]=1;matriz[j][i]=1;}else{matriz[i][j]=0;matriz[j][i]=0;}}}}}publicvoidimprimeMatriz(){System.out.println("Matriz de Adjacencia:\n");//Imprime a 1ª linha horizontal da matriz com o nº dos respectivos sensoresfor(inta=0;a<=this.redeSensores.size();a++){System.out.print(a+" ");}System.out.println();//Imprime todas as outras linhas horizontais da matrizfor(inti=0;i<this.redeSensores.size();i++){if(i<=8)System.out.print((i+1)+" ");elseif(i>8)System.out.print((i+1)+" ");for(intj=0;j<this.redeSensores.size();j++){if(j<9)System.out.print(matriz[i][j]+" ");elseSystem.out.print(matriz[i][j]+" ");}System.out.println();}}publicint[][]getMatriz(){returnthis.matriz;}publicvoidsetMatriz(int[][]matriz){this.matriz=matriz;}publicSensorgetSensor(inti){returnthis.redeSensores.get(i);}publicvoidaddSensor(Sensors){this.redeSensores.add(s);}publicArrayList<Sensor>getRedeSensores(){returnthis.redeSensores;}publicvoidsetRedeSensores(ArrayList<Sensor>redeSensores){this.redeSensores=redeSensores;}publicdoublecalculaDistancia(Sensors1,Sensors2){returnMath.sqrt((Math.pow((s1.getX()-s2.getX()),2)+Math.pow((s1.getY()-s2.getY()),2)));}@OverrideprotectedObjectclone()throwsCloneNotSupportedException{Redecopia=newRede(this.redeSensores);copia.setMatriz(this.matriz);returncopia;}@OverridepublicStringtoString(){Stringaux="";for(inti=0;i<redeSensores.size();i++){aux+="\nSensor "+(i+1)+" "+redeSensores.get(i).toString();}returnaux;}}
davidbuzatto
Você precisa clonar os componentes do objeto tbm!
importjava.util.ArrayList;importjava.util.List;publicclassRedeimplementsCloneable{privateList<Sensor>redeSensores;privateint[][]matriz;publicRede(List<Sensor>redeSensores){this.redeSensores=redeSensores;}publicRede(){}publicvoidinicializaMatriz(){}publicvoidimprimeMatriz(){}publicint[][]getMatriz(){returnthis.matriz;}publicvoidsetMatriz(int[][]matriz){this.matriz=matriz;}publicSensorgetSensor(inti){returnthis.redeSensores.get(i);}publicvoidaddSensor(Sensors){this.redeSensores.add(s);}publicList<Sensor>getRedeSensores(){returnthis.redeSensores;}publicvoidsetRedeSensores(List<Sensor>redeSensores){this.redeSensores=redeSensores;}publicdoublecalculaDistancia(Sensors1,Sensors2){returnMath.sqrt((Math.pow((s1.getX()-s2.getX()),2)+Math.pow((s1.getY()-s2.getY()),2)));}@OverrideprotectedObjectclone()throwsCloneNotSupportedException{List<Sensor>novaRedeSensores=newArrayList<Sensor>();for(Sensors:redeSensores){// precisa implementar o clone de sensor tbm!// se não der para implementar pq é uma classe que você está usando// cria uma nova instância e copie os valores manualmentenovaRedeSensores((Sensor)s.clone());}int[][]novaMatriz=newint[matriz.length][matriz[0].length];for(inti=0;i<matriz.length;i++){for(intj=0;j<matriz[i].length;j++){novaMatriz[i][j]=matriz[i][j];}}Redecopia=newRede(novaRedeSensores);copia.setMatriz(novaMatriz);returncopia;}@OverridepublicStringtoString(){Stringaux="";for(inti=0;i<redeSensores.size();i++){aux+="\nSensor "+(i+1)+" "+redeSensores.get(i).toString();}returnaux;}}
M
mayconfsbrito
Isso aí David eu implementei o método clone da forma que você ilustrou e deu certo, até que enfim!
Muito Obrigado pela ajuda e pela paciência meu caro, sou muito agradecido.
Ha! tive que implementar o método clone para cada instância do objeto Sensor também, segue abaixo este método.
A implementação de Clonable dá bastante mão de obra. Sempre que possível, uso minha classe Cloner , que serve para instâncias de qualquer classe que implemente Serializable.