主要内容
- 深拷贝与浅拷贝
- 算法:把数组排成最小的数
深拷贝与浅拷贝
浅拷贝
浅拷贝对于基本类型的属性会直接进行值传递,也就是对于基本类型的属性会复制一份给新的对象。而对于引用类型的属性,浅拷贝会进行引用的传递。因为传递的是引用,因此复制后的对象的此属性和原对象的属性指向同一个对象。
一段代码来证明:
1 2 3 4
| public class RefObj { }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class MyObj implements Cloneable{ private int val; private RefObj ref; public MyObj(int val,RefObj ref){ this.val=val; this.ref=ref; }
public static void main(String[] args) throws CloneNotSupportedException { final MyObj A = new MyObj(1, new RefObj()); final MyObj clone = (MyObj)A.clone(); System.out.println(A == clone); System.out.println(A.ref == clone.ref); } }
|
深拷贝
深拷贝对于基本类型的变量的处理方法和浅拷贝一致,都是复制一份给新的对象。而对于引用类型,深拷贝会复制引用的对象,然后让克隆产生的新对象中的对应属性指向这个复制的引用对象。
那么如何实现深拷贝呢?
常见的有两种方法,一种是重新Cloneable接口中的clone()方法
- 方案一:
1 2 3 4 5 6 7 8 9
| public class RefObj implements Cloneable{
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class MyObj implements Cloneable{ public int val; public RefObj ref; public MyObj(int val,RefObj ref){ this.val=val; this.ref=ref; } @Override protected Object clone() throws CloneNotSupportedException { MyObj clone = (MyObj)super.clone(); clone.ref= (RefObj) clone.ref.clone(); return clone; }
public static void main(String[] args) throws CloneNotSupportedException { final MyObj A = new MyObj(1, new RefObj()); final MyObj clone = (MyObj)A.clone(); System.out.println(A == clone); System.out.println(A.ref == clone.ref); }
}
|
- 方案二,通过序列化来实现深拷贝
1 2 3 4
| public class RefObj implements Serializable {
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class MyObj implements Serializable { public int val; public RefObj ref; public MyObj(int val,RefObj ref){ this.val=val; this.ref=ref; }
public static void main(String[] args) throws IOException, ClassNotFoundException {
final MyObj obj = new MyObj(1, new RefObj()); ByteArrayOutputStream baos=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(baos); oos.writeObject(obj);
oos.flush();
ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); final MyObj cloneObj = (MyObj) ois.readObject();
System.out.println(obj == cloneObj); System.out.println(obj.ref == cloneObj.ref);
}
|
必须实现标记接口Serializable
算法:把数组排成最小的数
题目:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:
任意两个拼接后进行比较,比如:s1+s2,和s2+s1,如果s1+s2大,那说明s2应该放前面,所以按这个规则,s2就应该排在s1前面.按照这个比较的方法,按照冒泡排序的思路,对数组进行排序即可,最后拼接。
解法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.ArrayList;
public class Solution { public String PrintMinNumber(int [] numbers) { for(int i=0;i<numbers.length;i++){ for(int j=0;j<numbers.length-i-1;j++){ long a=Long.valueOf(numbers[j]+""+numbers[j+1]); long b=Long.valueOf(numbers[j+1]+""+numbers[j]); if(b<a){ int tmp=numbers[j]; numbers[j]=numbers[j+1]; numbers[j+1]=tmp; } } } StringBuilder sb=new StringBuilder(); for (int i=0;i<numbers.length;i++){ sb.append(numbers[i]); } return sb.toString(); } }
|