[RESOLVIDO] Problemas na referência de objetos

Galera,

Então, estou com um problema que acredito ser iniciante, apesar de já programar há um tempo e nunca ter acontecido isso comigo. hehehe!

Observem esse código:

Telefone telefone;

telefone = new Telefone();
telefone.setNumero("88888888");
System.out.println(telefone);
System.out.println(telefone.getNumero());
		
telefone = new Telefone();
telefone.setNumero("12345678");
System.out.println(telefone);
System.out.println(telefone.getNumero());

Quando compilo, sai o seguinte resultado:

br.com.sistema.entity.Telefone@1f
88888888
br.com.sistema.entity.Telefone@1f
12345678

O problema é o seguinte, eu estou jogando essas duas referências em um ArrayList (posteriormente), porém, como a referência está saindo com a mesma identificação (br.com.sistema.entity.Telefone@1f), eu não consigo usar o método “indexOf(objeto)”, ou o “remove(objeto)”.

Como eu estou dando “New” na variável “telefone”, não era para ele estar criando uma nova referência (Por ex: br.com.sistema.entity.Telefone@3b78dsf) ?

Valeu!!!

Sim, você consegue. É apenas como se você estivesse dando um telefone.toString().
São referências distintas, pode adicionar a sua list sem problemas e utilizar os métodos que desejar.

Este formato é apenas o formato em String do seu Objeto Telefone.
Abraços.

Kired bom d mais? Vc tem que fazer uma subscrita do metodo toString() da classe Object na sua Classe, para poder exibir o conteudo do seu Objeto.

Opa,

Valeu pelas respostas, galera!!!

Mas o problema é que quando eu chamo o método “remove(objeto)”, ou “indexOf(objeto)”, ele não acha o objeto correto, ele remove o primeiro objeto da lista, mesmo que o objeto que eu mande seja na verdade o quinto ou sexto da lista, ou no caso do indexOf, ele sempre retorna o ID: 0 . Sinceramente, não entendo o por que disso… hehehe!

Quanto ao toString(), que eu saiba, se eu não reescrever ele, ele retorna o ID do objeto na memória, por isso que eu acho que deveriam vir números diferentes ali, e não os mesmos. Me corrijam se eu estiver errado.

Valeu!!!

na realidade o toString() retorna o objeto em questão, no seu caso o objeto telefone.

se vc fizer isso:

telefone.setNumero("12345678"); System.out.println(telefone);

E nao tiver um toString() subscrito vc vai receber o proprio resultado que vc sitou, agora se vc quiser imprimir o conteudo do objeto em Strings, como por exemplo o numero ai vc teria que fazer a subscrita como por exemplo:

[code]public String toString(){

return “Numero do telefone” +numeroTelefone;

}
[/code]

adicione no ArrayList o “getNumero.toString()”
ex: arrayListExemplo.add(telefone.getNumero().toString())
Funciona perfeitamente …

Opa,

Agradeço novamente as respostas!

Mas meu problema é o seguinte:

Eu entendo a utilidade do “toString()”, porém, não é minha intenção altera-lo agora.

Eu criei um ArrayList de telefones mesmo:

List<Telefone> telefones = new ArrayList<Telefone>

e vou adicionando os telefones, no caso, aqueles dois que eu criei por exemplo:

Telefone telefone;

telefone = new Telefone();
telefone.setNumero("88888888");
System.out.println(telefone);
System.out.println(telefone.getNumero()); 

telefones.add(telefone); //adicionei o "Objeto 1"
          
telefone = new Telefone();  
telefone.setNumero("12345678");  
System.out.println(telefone);  
System.out.println(telefone.getNumero());

telefones.add(telefone); //adicionei o "Objeto 2"

O problema disso é o seguinte:

Eu estou trabalhando em uma página jsf, em que uma Pessoa (classe), pode ter vários telefones (Classe Telefone). Para isso, criei uma parte da página em ajax que vai adicionando telefones a lista de telefones.

Quando e cada telefone que o cara adiciona, ele chama o seguinte método:


public void salvaTelefone() {
       colaboradorInEdit.getTelefones().add(telefone);
       this.telefone = new Telefone();
}

Porém, quando vou remover um telefone dessa lista, por exemplo, eu uso um a tag <f:setPropertyActionListener> do JSF, que joga um objeto selecionado ao ManagedBean. Eu fiz testes, e vi que ele está jogando o objeto correto, porém, quando ele vai remover esse objeto da lista, ele remove sempre o primeiro objeto da lista (na posição 0), como se fossem todos objetos iguais, com a mesma referência na memória.

Não sei se fui claro, eu evitei explicar o meu problema desde o início porque é meio grande mesmo, hehehehe, mas acho que não estava me expressando muito bem…

Valeu, Galera!

Se a cada vez que você adiciona um Telefone você cria uma nova instância do seu Objeto, não haverá problemas de referência, ou seja:

Telefone telefone = new Telefone(); list.add(telefone);

Você pode adicionar isso a um Loop sem problemas que não vai sobrescrever seu objeto telefone, sempre será criado (instanciado) um novo. Se fizer dessa forma e adicionar 3 objetos ao list e depois der:

//posição 3, já que List inicia em 0 list.remove(2);
Você removeu o objeto 3. O que pode estar acontecendo é um erro na forma como implementou a remoção.
Abraços.

[code]Telefone telefone;

telefone = new Telefone();
telefone.setNumero(“88888888”);
System.out.println(telefone);
System.out.println(telefone.getNumero());

telefones.add(telefone); //adicionei o “Objeto 1”

telefone = new Telefone();
telefone.setNumero(“12345678”);
System.out.println(telefone);
System.out.println(telefone.getNumero());

telefones.add(telefone); //adicionei o "Objeto [/code]

Humm, pelo que eu to vendo se vc ta usando o mesmo objeto pra setar o telefone ele vai somente reescrever o telefone, esse metodo seu teria que estar dentro de um loop ou entao vc criar um novo objeto.

Everton, engano seu amigo. Ele somente usa a mesma variavel mas cria uma nova referência, já que ele utiliza novamente o new, concorda comigo? :slight_smile:

O que ele fez seria o mesmo que a um loop, digamos assim:

for(int i =0; i<10; i++){ Telefone telefone = new Telefone(); }

Variavél com o mesmo nome mas com referência distintas. A questão é como ele está implementando o remove mesmo.
Abraços.

nelll olho de aguia kkk agora que eu vi rsrs, certo vc amigo!!

Errado. Ele está a fazer new, logo a criar um novo objecto. Aparentemente não vejo qualquer problema no código para provocar essa situação.

@nel
Realmente, se eu passar direto o número da posição, ele remove corretamente. O problema é que eu não tenho como passar o número da posição, eu só posso passar o objeto diretamente e é ai que ta rolando o problema, pois, pelo que parece, os objetos estão com a mesma referencia.

@evertonsilvagomesjava
É engraçado, pois eu consigo listar esse Array, e ele mostra todos os objetos certinho. Se eu selecionar um deles e dar um “telefones.get(2)”, ele tras o telefone correto. Porém, como todos os objetos parecem ter a mesma referência (não sei como acontece isso, pois se eles tivessem a mesma referência mesmo, era para reescrever os valores do objeto já criado, e não criar um novo objeto), eu não consigo utilizar o método “telefones.remove(objeto)”, nem o “telefones.indexOf(objeto)” ( Ele retorna sempre zero, pois a referencia é a mesma em todos os objetos).

É bem estranho isso, ta meio fora do que eu conheço na teoria do Java. hehehe!

Valeu novamente, pessoal!!!

@pmlm
Exatamente. Por isso não entendo o que está acontecendo. Já cheguei a achar que fosse problema do Eclipse, ou da JVM, mas sei lá, to o dia inteiro tentando desvendar esse problema. hehehe!

Que isso Everton! hehe…

Kired, se está enviando um único objeto, faça assim amigo:

int index = suaLista.indexOf(telefone); suaLista.remove(index);

Ok?

Abraços.

@nel
Então, já tentei isso, não funcionou também. Até porque eu acho que o próprio método “remove(objeto)”, faz isso internamente, usa o “indexOf” primeiro para depois remover.

A variável “index” vem com o valor 0, pois, apesar de todos os objetos da lista possuirem valores diferentes nos seus atributos, eles tem o mesmo valor de referencia (dando um “toString()”, vem a mesma referencia).

É tão verdade que todos os objetos estão com a mesma referencia, que se eu utilizar o método “lastIndexOf”, ele retorna o último objeto da lista. hehehe!

Loucura total!

Agradeço a resposta de todos!

Vou continuar procurando uma solução “teórica” pra isso.

Valeu!!!

Como é a classe Telefone? Implementaste o equals/hashCode?

Amigo, ai o problema já está sendo outro. A questão é como você está efetuando isso. Se usar da forma como indiquei é para funcionar, agora, tudo depende da forma como você está fazendo isso.

Se está utilizando JSF é para o seu Objeto chegar preenchido ao seu método remover e nele você remove o Objeto.
Se tentar efetuar testes da forma como está fazendo realmente não vai funcionar. Crie assim, por exemplo:

[code]Telefone telefone = new Telefone();
//seus setters

Telefone t = new Telefone();
//seus setter[/code]

Se enviar o t ou telefone para buscar o indice na lista ele com absoluta certeza vai encontrar o Objeto correto, mas, se enviar valores distintos do Objeto mas com a mesma variavél de referência, ele sempre vai buscar o primeiro item. Sendo sincero, acho que você está fazendo uma “Tempestade em um copo d’agua”, ou seja, está complicado o que é simples.

Abraços.

@pmlm
Olha, me perguntando isso, me chamou a atenção pro hashCode(), será que isso tem a ver?

Porque, na verdade, o equals() e o hashCode() estão baseados no “id” da classe Telefone, mas como ela ainda não foi persistida, esse id é nulo, então não tem como diferenciar uma classe da outra pelo “equals()”.

Será que é isso?

Valeu! Abraços!

@Entity
@Table(name = "TELEFONE")
public class Telefone implements Serializable {

	private static final long serialVersionUID = -5765740267067209499L;

	@Id
	@GeneratedValue(strategy = IDENTITY)
	private Long id;
	
	@Column(name = "ddd")
	private String ddd;
	
	@Column(name = "numero")
	private String numero;
	
	@Column(name = "ramal")
	private String ramal;
	
	@Enumerated(EnumType.STRING)
	private TipoTelefone tipoTelefone;

	public Telefone(){

	}

	public Long getId() {
		return id;
	}

        //getters & setters...

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Telefone other = (Telefone) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
}

Só para deixar claro uma coisa:

Seu Object: Telefone.
Sua referência: telefone (no seu caso)

Mesmo que você sempre dê new, a referência ao Objeto será sempre a mesma mas como há instâncias distintas ele é capaz de armazenar valores distintos, entendeu? :slight_smile: