Cópia de variáveis para dentro de um método?

Olá,

Tenho a seguinte dúvida:

no exemplo abaixo, depois de executar o método secondMap(subMap), a variável submap contém o par <“SubMap”, “Second”>.

O subMap não deveria retornar vazio, porque supostamente estaria a passar para dentro do método uma cópia do subMap definido no método mapping2()?

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class Mapping {
	
	
	// Second test
	public void mapping2()
	{
		Map map = new HashMap();
		Map subMap = new HashMap();
		
		map.put("first", subMap);
		
		secondMap(subMap);
			
		Map secondMap = (Map) map.get("first");
		Collection col = secondMap.values();
		Iterator iter = col.iterator();
		
		while(iter.hasNext())
		{
			System.out.println("String - " + (String) iter.next());
		}
	}
	
	public void secondMap(Map dest)
	{
		dest.put("SubMap", "Second");
	}
	
	//-----------------------------------

	
	public static void main(String[] args) {
		System.out.println("Mapping 2");
		new Mapping().mapping2();
	}
}

Obrigado,
Pedro

Passar algo como parâmetro não faz uma cópia do objeto.

Para fazer uma cópia do objeto, se ele for clonável, você tem de chamar explicitamente o método clone.

Não entendi o que você está falando.

Você quer dizer que como você inseriu o subMap no map este tem que ficar vazio?

No seu caso vc criou um objeto map e está inserindo em outro map. Você então popula o map q vc inseriu no outro map. No proximo passo, obtem novamente o map q foi inserido, apenas criando uma nova referência a ele em secondMap.

Ou seja, você possui 2 maps e 3 referencias de Map entendeu?

Você não passa o objeto em si, mas sim o valor de sua referência, seu endereço de memória, o lugar em que ele se econtra.

Entendeu?

Entao pedrosacosta como você passou a referencia do seu objeto subMap ele inclui o valor Second dentro…

o parametro dest passa a ter a mesma referencia de subMap logo os dois possuem este valor Second, porém o subMap no método de fora e o dest apenas naquele escopo do método que ele pertence…

Quando vc declara uma variavel dentro de um metodo esta variavel so existe para aquele metodo.

Na assinatura de um metodo vc tambem esta criando uma variavel.

Declare a variavel “subMap” como variavel de instancia

public class Mapping { 	
 	
        private Map subMap = new HashMap()

 	public void mapping2()
 	{ /*..*/ }

        public void secondMap(Map dest)
 	{ /*..*/ }

}

Repare que vc nao consegue colocar em uma variavel de um metodo o tipo de acesso(public, private …), isso ja me da a deixa que ali eu nao externalizo a variavel (referencia) e sim o seu valor

Eu ainda não percebi bem.

O exemplo completo está nas classes abaixo.

1 - eu entendo o First test.
2 - eu pensava que quando passamos um objecto ou uma variável, passamos cópia do objecto e uma cópia da variável. No ponto respeitante ao da variável (ver o third test) eu compreendo perfeitamente. Passa-se uma cópia da variável para dentro do método.

No que diz respeito ao objecto, eu percebo quando dizem que se está a passar uma cópia da referência que está a apontar para o objecto. Se isto é verdado, o que se passa com o Fourth test, em que estou à espera de ver o resultado 1, e continuo obter o 0?

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class Mapping {
	
	// First test
	public void mapping1()
	{
		Map map = new HashMap();
		Map subMap = new HashMap();
		
		map.put("first", subMap);
		subMap.put("SubMap", "Second");
		
		Map secondMap = (Map) map.get("first");
		Collection col = secondMap.values();
		Iterator iter = col.iterator();
		
		while(iter.hasNext())
		{
			System.out.println("String - " + (String) iter.next());
		}
	}
	//-------------------------------------
	
	// Second test
	public void mapping2()
	{
		Map map = new HashMap();
		Map subMap = new HashMap();
		
		map.put("first", subMap);
		
		secondMap(subMap);
			
		Map secondMap = (Map) map.get("first");
		Collection col = secondMap.values();
		Iterator iter = col.iterator();
		
		while(iter.hasNext())
		{
			System.out.println("String - " + (String) iter.next());
		}
	}
	
	public void secondMap(Map dest)
	{
		dest.put("SubMap", "Second");
	}
	
	//-----------------------------------

	// third test
	public void mapping3()
	{
		int i = 0;
		
		add(i);
		System.out.println(i);
	}
	
	public void add(int i)
	{
		i++;
	}
	
//	-----------------------------------
	
	// fourth test
	public void mapping4(){
		Counter c = new Counter();
		
		add(c);
		
		System.out.println("Counter: " + c.getI());
	}
	
	public void add(Counter counter)
	{
		counter.setI(counter.getI()+1);
	}
	
	//-----------------------------------------
	
	public static void main(String[] args) {
		System.out.println("First Test");
		new Mapping().mapping1();
		System.out.println("Second Test");
		new Mapping().mapping2();
		System.out.println("Third Test");
		new Mapping().mapping3();
		System.out.println("Fourth Test");
		new Mapping().mapping4();
	}
}

public class Counter {
	int i = 0;
	
	public int getI()
	{
		return i;
	}
	
	public int setI(int i)
	{
		return i;
	}
}

Output:

First Test
String - Second
Second Test
String - Second
Third Test
0
Fourth Test
Counter: 0

Obrigado,
Pedro

Vamos la

// fourth test
 	public void mapping4(){
 		Counter c = new Counter();
 		
 		add(c);
 		
 		System.out.println("Counter: " + c.getI());
 	}
 	
 	public void add(Counter counter)
 	{
 		counter.setI(counter.getI()+1);
 	}

No metodo add o q vc mexe dentro dele nao se reflete na variavel c no metodo mapping4.
Porque? Quando eu faco add(Counter counter) este counter e uma nova referencia na pilha não sendo a mesma referencia da variavel c do metodo mapping4.

Outra, o seu metodo setI(int i) esta errado. Veja o codigo comentado.

 public class Counter {
 	int i = 0;
 	
 	public int getI()
 	{
 		return i;
 	}
 	
 	public int setI(int i)
 	{
 		return i;
                //certo
               // this.i = i
 	}
 }