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):
public void verificaDesconexos(Rede r, int raiz, Grafo g) throws Exception {
int n = this.grafo.numVertices();
int verifica = raiz;
boolean aux = false;
//Configura uma rede com algoritmo de Prim toda ativa
Rede redeTodaAtiva= new Rede();
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());
public boolean isAtivacao() {
return ativacao;
}
public ArrayList<Sensor> getRedeSensores() {
return this.redeSensores;
}
public void setRedeSensores(ArrayList<Sensor> redeSensores) {
this.redeSensores = redeSensores;
}
Resultado da impressão da linha 11 e 12:
TESTE false
TESTE false
Sei que deve ser uma coisa boba. Aguardo uma mãozinha…
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.
Olhe o exemplo:
[code]public class Pessoa {
private String nome;
private String sobrenome;
public String getNome() {
return nome;
}
public void setNome( String nome ) {
this.nome = nome;
}
public String getSobrenome() {
return sobrenome;
}
public void setSobrenome( String sobrenome ) {
this.sobrenome = sobrenome;
}
@Override
public String toString() {
return getNome() + " " + getSobrenome();
}
@Override
protected Object clone() {
Pessoa p = new Pessoa();
p.setNome( getNome() );
p.setSobrenome( getSobrenome() );
return p;
}
}[/code]
[code]public class Main {
public static void main(String[] args) {
// cria uma pessoa
Pessoa p1 = new Pessoa();
p1.setNome( "João" );
p1.setSobrenome( "Silva" );
// "aponta" p2 para o endereço de p1
Pessoa p2 = p1;
// clona o objeto p1, apontando p3 para a nova Pessoa criada
Pessoa p3 = ( Pessoa ) p1.clone();;
// mostra todo mundo
System.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 objeto
p1.setSobrenome( "Sauro" );
// muda as propriedades de p3
p3.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 :D
System.out.println( p3 );
}
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.
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.
import java.util.ArrayList;
public class Rede implements Cloneable {
private ArrayList<Sensor> redeSensores = new ArrayList<Sensor>();
private int[][] matriz;
public Rede(ArrayList<Sensor> redeSensores) {
this.redeSensores = redeSensores;
}
public Rede() {
}
public void inicializaMatriz() {
//inicializa matriz com o número de sensores(incluindo o sink)
setMatriz(new int[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 um
for (int i = 0; i < this.redeSensores.size(); i++) {
for (int j = 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;
}
}
}
}
}
public void imprimeMatriz() {
System.out.println("Matriz de Adjacencia:\n");
//Imprime a 1ª linha horizontal da matriz com o nº dos respectivos sensores
for (int a = 0; a <= this.redeSensores.size(); a++) {
System.out.print(a + " ");
}
System.out.println();
//Imprime todas as outras linhas horizontais da matriz
for (int i = 0; i < this.redeSensores.size(); i++) {
if(i <= 8)
System.out.print((i+1) + " ");
else if(i > 8)
System.out.print((i+1) + " ");
for (int j = 0; j < this.redeSensores.size(); j++) {
if(j < 9)
System.out.print(matriz[i][j] + " ");
else
System.out.print(matriz[i][j] + " ");
}
System.out.println();
}
}
public int[][] getMatriz(){
return this.matriz;
}
public void setMatriz(int[][] matriz) {
this.matriz = matriz;
}
public Sensor getSensor(int i){
return this.redeSensores.get(i);
}
public void addSensor(Sensor s) {
this.redeSensores.add(s);
}
public ArrayList<Sensor> getRedeSensores() {
return this.redeSensores;
}
public void setRedeSensores(ArrayList<Sensor> redeSensores) {
this.redeSensores = redeSensores;
}
public double calculaDistancia(Sensor s1, Sensor s2) {
return Math.sqrt((Math.pow((s1.getX() - s2.getX()), 2) + Math.pow((s1.getY() - s2.getY()), 2)));
}
@Override
protected Object clone() throws CloneNotSupportedException {
Rede copia = new Rede(this.redeSensores);
copia.setMatriz(this.matriz);
return copia;
}
@Override
public String toString() {
String aux = "";
for (int i = 0; i < redeSensores.size(); i++) {
aux += "\nSensor " + (i + 1) + " " + redeSensores.get(i).toString();
}
return aux;
}
}
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.
public class Cloner {
public static Serializable getClone(Serializable objeto) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos;
ObjectOutputStream oos = new ObjectOutputStream (bos= new ByteArrayOutputStream());
try {
oos.writeObject(objeto);
oos.flush();
}
finally {
oos.close();
}
ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream(bos.toByteArray()));
try {
return (Serializable) ois.readObject();
}
finally {
ois.close();
}
}
}