——- android培训、java培训、期待与您交流! ———-
JAVA中复制数组元素值:(深拷贝)
在JAVA里面,可以用复制语句“A=B”给基本类型的数据传递值,但是如果A,B是两个同类型的数组,复制就相当于将一个数组变量的引用传递给另一个数组;如果一个数组发生改变,那么引用同一数组的变量也要发生改变。
public static void main(String[] args) {
int[] a={3,1,4,2,5};
int[] b=a;
b[0]=10;
System.out.println(b+" "+a);
System.out.println(b==a);
System.out.println(b[0]+" "+a[0]);
}
//结果: [I@15db9742 [I@15db9742
// true
// 10 10
为此就需要新建一个数组,而不单单是复制引用
1、使用FOR循环,将数组的每个元素复制
(当底层不是基本数据类型时:需要将每个对象调用clone方法,才能实现真正的复制)
public static void main(String[] args) {
int[] a={3,1,4,2,5};
int[] b=new int[a.length];
for(int x=0;x<a.length;x++){
b[x]=a[x];
}
b[0]=10;
System.out.println(b[0]+" "+a[0]);
//输出 : 10 3
int[][] a2={{3,1,4,2,5},{4,2}};
int[][] b2=new int[a2.length][a2[0].length];
for(int x=0;x<a2.length;x++){
b2[x]=a2[x];
}
b2[0][0]=10;
System.out.println(b2[0][0]+" "+a2[0][0]);
}
// 输出: 10 10
/*
int[][] a2={{3,1,4,2,5},{4,2}};
int[][] b2=new int[a2.length][a2[0].length];
for(int x=0;x<a2.length;x++){
b2[x]=a2[x].clone();
}
b2[0][0]=10;
System.out.println(b2[0][0]+" "+a2[0][0]);
// 输出:10 3
*/
2、使用clone方法,得到数组的值,而不是引用
/*
int[] a={3,1,4,2,5};
int[] b=a.clone();
b[0]=10;
System.out.println(b[0]+" "+a[0]);
// 输出:10 3
*/
3、使用System.arraycopy(s,start1,t,start2,length)方法
public static void main(String[] args) {
int[] a={3,1,4,2,5};
int[] b=new int[a.length];
System.arraycopy(a, 0, b, 0, a.length);
b[0]=10;
System.out.println(b[0]+" "+a[0]);
// 输出:10 3
}
/*
注:
s是原数组,t是目标数组,start1&start2是开始复制下标,length一般是s的长度,
由于arraycopy方法不给目标数组分配内存空间,所以必需要先为t分配内存空间!
*/
注意:
1.上面方法中arraycopy效率较高。
2. 以上方法,只限一维数组,多维数组,要具体到一维复制才能实现复制数组元素的值。
3. clone 和 arraycopy对二维数组进行复制时,是浅拷贝
JAVA中复制集合元素值:(深拷贝)
// 为了验证方便,这里不再覆盖 toString() 方法
public class FuZhi {
public static void main(String[] args) {
Student c = new Student("zhan",22);
Student d = new Student("zhan",22);
Student e = new Student("zhan",22);
Student f = new Student("zhan",22);
List<Student> li = new ArrayList<Student>();
li.add(c);
li.add(e);
li.add(d);
li.add(f);
List<Student> li2 = new ArrayList<Student>();
li2=li;
li.set(0, new Student("wang",23));
// 结果1 System.out.println(li2.toString());
System.out.println("li[0]:\t"+li.get(0)
+"\r\nli2[0]\t"+li2.get(0)
+"\r\n是否相等:"+(li2.get(0)==li.get(0)));
}
}
class Student{
private String name;
private int age;
Student(String name, int age){
this.name=name;
this.age =age;
}
// public String toString(){ //结果1
// return name+" "+age;
// }
}
/*
输出结果1、:
[wang 23, zhan 22, zhan 22, zhan 22]
输出结果2、:
li[0]: Hello.Student@15db9742
li2[0]: Hello.Student@15db9742
是否相等:true
*/
ArryList()深层拷贝方法.
1、 最简洁的 new ArrayList( src)
public class FuZhi {
public static void main(String[] args) {
Student c = new Student("zhan",22);
Student d = new Student("zhan",22);
Student e = new Student("zhan",22);
Student f = new Student("zhan",22);
List<Student> li = new ArrayList<Student>();
li.add(c);
li.add(e);
li.add(d);
li.add(f);
List<Student> li2 = new ArrayList<Student>();
// 建立一个集合副本 ,复制内部所有元素
li2 =new ArrayList<Student>(li);
li.set(0, new Student("wang",23));
System.out.println("li[0]:\t"+li.get(0)+"\r\nli2[0]\t"
+li2.get(0)+"\r\n是否相等:"
+(li2.get(0)==li.get(0)));
}
}
class Student {
private String name;
private int age;
Student(String name, int age){
this.name=name;
this.age =age;
}
public String toString(){
return name+" "+age;
}
}
/*
li[0]: wang 23
li2[0] zhan 22
是否相等:false
*/
2、 覆盖 clone(不建议)
通过覆盖 Object 中的 clone(),进行复制
不过只限一维,多维需要多层覆盖,很麻烦
import java.util.ArrayList;
// 首先类 必须实现 Cloneable 接口
public class TestClone implements Cloneable {
private ArrayList<String> arrayList = new ArrayList<String>();
// 第二 最高权限覆写 clone() 方法
public TestClone clone() {
TestClone testClone = null;
try {
testClone = (TestClone) super.clone();
testClone.arrayList =
(ArrayList<String>) this.arrayList.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return testClone;
}
public ArrayList<String> getArrayList() {
return this.arrayList;
}
public void setValue(String value) {
arrayList.add(value);
}
public static void main(String[] args) {
TestClone testClone = new TestClone();
testClone.setValue("张三");
//调用 clone 方法
TestClone testClone1 = testClone.clone();
testClone1.setValue("李四");
System.out.println(testClone.getArrayList());
System.out.println(testClone1.getArrayList());
}
}
/*
运行结果:
[张三]
[张三, 李四]
*/
3、通过序列化
就是把ArrayList的原来的对象进行序列化,然后通过反序列化读取出来,就可以了。
当然,记着放到集合中的元素也要能够序列化,所以必须实现Serializable接口。
package test;
import java.io.Serializable;
// 实现序列化需要实现接口 Serializable
public class Userinfo implements Serializable
{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 下面是测试:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
List src = new ArrayList(2);
Userinfo ui1 = new Userinfo();
ui1.setId(1);
ui1.setName("aaa");
src.add(ui1);
Userinfo ui2 = new Userinfo();
ui1.setId(2);
ui1.setName("bbb");
src.add(ui2);
List dest = new ArrayList(2);
TestMain test = new TestMain();
try {
dest = test.deepCopy(src);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(src==dest);
Userinfo u = (Userinfo)src.get(0);
Userinfo uu = (Userinfo)dest.get(0);
uu.setName("dkkdkddk");
System.out.println(u.getName());
System.out.println(uu.getName());
}
// 复制代码
public List deepCopy(List src) throws IOException, ClassNotFoundException{
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in =new ObjectInputStream(byteIn);
List dest = (List)in.readObject();
return dest;
}
}
/*
输出结果:
false
bbb
ccc
*/