Java對象和集合拷貝

Java對象和集合的拷貝問題

1.今天學習了Java拷貝的問題,其實以前在學習c++的時候也知道對象的深拷貝和淺拷貝的區別,算是有一定的基礎,只是在Java中沒有深入,前幾天在工作中遇到這個問題,當時爲了簡單,繞過了這個問題,現在用例子說明這個問題。
基礎類Animal:
class Animal {
	private String name;
	private String color;
	
	public Animal(String name, String color) {
		this.name = name;
		this.color = color;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public String toString(){
		return "name:"+this.name+",clor:"+this.color;
	}
}
測試類:
public class DemoClone {
	public static void main(String[] args) {
		ArrayList<Animal> list1 = new ArrayList<Animal>();
		list1.add(new Animal("dog","mud"));
		list1.add(new Animal("pig","black"));
		ArrayList<Animal> list2 = new ArrayList<Animal>(list1);
		list1.get(0).setName("dog1");
		list1.get(1).setName("pig1");
		System.out.println("list1 is ########################");
		for(Animal temp : list1){
			System.out.println(temp);
		}
		System.out.println("list2 is ########################");
		for(Animal temp : list2){
			System.out.println(temp);
		}
	}
}
測試結果:
list1 is ########################
name:dog1,clor:mud
name:pig1,clor:black
list2 is ########################
name:dog1,clor:mud
name:pig1,clor:black
測試評定:通過測試我們發現Java API自帶的拷貝函數屬於淺拷貝,當修改原來的集合list1時,拷貝的集合list2中的數據也同樣發生了改變,這就是淺拷貝,原因是list1和list2指向了內存中的同一個內存單元(其中放置着Animal的對象),所以結果是上述所示
想要實現深拷貝必須讓集合中的元素實現Cloneable接口,實現clone方法,這跟c++不同,c++只需要在拷貝函數中重新申請內存空間,存放原對象的內容,即可實現!
正確方法:
基礎類Animal:
class Animal implements Cloneable{
	private String name;
	private String color;
	
	public Animal(String name, String color) {
		this.name = name;
		this.color = color;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public Animal clone(){
		Animal clone = null;
		try{
			clone = (Animal)super.clone();
		}catch(Exception e){
			e.printStackTrace();
		}
		return clone;
	}
	public String toString(){
		return "name:"+this.name+",clor:"+this.color;
	}
}
可以看出基礎類Animal實現了Cloneable,實現其中clone方法,
測試類:
public class DemoClone {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ArrayList<Animal> list1 = new ArrayList<Animal>();
		list1.add(new Animal("dog","mud"));
		list1.add(new Animal("pig","black"));
		ArrayList<Animal> list2 = new ArrayList<Animal>(list1.size());
		Iterator it = list1.iterator();
		while(it.hasNext()){
			Animal temp = (Animal)it.next();
			list2.add(temp.clone());
		}
		list1.get(0).setName("dog1");
		list1.get(1).setName("pig1");
		System.out.println("list1 is ########################");
		for(Animal temp : list1){
			System.out.println(temp);
		}
		System.out.println("list2 is ########################");
		for(Animal temp : list2){
			System.out.println(temp);
		}
	}

}
測試結果:
list1 is ########################
name:dog1,clor:mud
name:pig1,clor:black
list2 is ########################
name:dog,clor:mud
name:pig,clor:black
測試評定:
符合我們的預期要求!


基礎類不變,我們進行Java對象的拷貝
測試類:
public class DemoClone {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Animal animal1 = new Animal("dog","mud");
		Animal animal2 = animal1.clone();
		animal1.setName("dog1");
		System.out.println("animal1 is #######################");
		System.out.println(animal1);
		System.out.println("animal2 is #######################");
		System.out.println(animal2);
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章