java 数组复制
http://www.cnblogs.com/zhengbin/p/5671403.html
http://www.cnblogs.com/jjdcxy/p/5870524.html
Java数组拷贝主要有四种方法,分别是循环赋值,System.arraycopy(),Arrays.copyOf()(或者Arrays.copyOfRange)和clone()方法。下面分别介绍一下这几种拷贝。
循环拷贝(速度相对比较慢)
循环拷贝其实没什么好说的啦,就是用一个for循环进行元素的逐个拷贝,进行深拷贝或者浅复制这个大家可以自己把握。
System.arraycopy(浅拷贝)
这个是系统提供的拷贝方式,也是我们推荐使用的拷贝方式,它是浅拷贝,也就是说对于非基本类型而言,它拷贝的是对象的引用,而不是去新建一个新的对象。通过它的代码我们可以看到,这个方法不是用java语言写的,而是底层用c或者c++实现的,因而速度会比较快。
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
通过源代码我们可以看到,关键字native说明它不是用java语言写的,而是调用其他语言的代码。
Arrays.copyOf(浅拷贝)
这个方法也是浅拷贝,为什么呢?我们看一下它的源代码就知道了。
public static byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
实际上它调用的就是System.arraycopy,所以肯定也是浅拷贝。
Object.clone
clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝。
对象拷贝
首先讲一下对象的拷贝,它是深拷贝,大家可以用对象去测试一下。下面我们看一下它的源代码:
protected native Object clone() throws CloneNotSupportedException;
这里也有native关键字,所以也是底层的C语言实现的。
还要注意的是,这里修饰符是protected,也就是说,我们创建了一个Object类以后,是不能直接调用这个clone()方法的,因为protected关键字只允许同一个包内的类和它的子类调用,所以我们声明一个object类时,肯定不是同一个包内,所以就不能去调用它。
要调用这个方法,就需要我们写一个类,然后声明实现cloneable接口就好了,不需要去显示地声明继承于object,因为java中的类如果不显示说明父类的话,默认父类就是object。然后我们继承这个方法:
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
这里需要是,为了能够在不同包内去调用这个方法,我们需要把这个权限升级为public。现在我们就可以调用这个类的clone()方法去拷贝我们的类了。
数组拷贝
对于数组而言,它不是简单的将引用赋值为另外一个数组引用,而是创建一个新的数组。但是我们知道,对于数组本身而言,它它的元素是对象的时候,本来数组每个元素中保存的就是对象的引用,所以,拷贝过来的数组自然而言也是对象的引用,所以对于数组对象元素而言,它又是浅拷贝。我们用以下代码验证一下:
class Aby implements Cloneable{
public int i;
public Aby(int i) {
this.i = i;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
public class Solution {
public static void main(String[] args) throws CloneNotSupportedException {
Aby aby1 = new Aby(1);
Aby aby2 = (Aby) aby1.clone();
aby1.i = 2;
System.out.println(aby1.i); //2
System.out.println(aby2.i); //1
Aby[] arr = {aby1,aby2};
Aby[] arr2 = arr.clone();
arr2[0].i = 3;
System.out.println(arr[0].i); //3
System.out.println(arr2[0].i); //3
}
}
java 数组复制的更多相关文章
- java数组复制的几种常见用法
1.1数组复制的几种常见用法 1.1.1System.arraycopy的用法 int[] src = {1,3,5,7,9,11,13,15,17}; int[] dest = {2,4,6,8,1 ...
- java数组复制的方式和效率比较
java中,数组的复制有以下三种方式: 1. 调用System.arraycopy(Arrays.copyOfRange可以当作第四种,但是底层调用的是System.arraycopy,所以,认为是同 ...
- Java数组复制、遍历、反转
/* 1.数组长度,直接length 即可! 2.min()/max(),需要调用库! 3.数组的复制 ,遍历复制,或者直接命名相等 即可! 4.数组反转时,直接折中即可!对调两重循环麻烦! */ i ...
- Java 数组复制之clone方法
一.源码 public class Test1 { public static void main(String[] args) { // Student[] arrs = new Student[] ...
- Java数组复制
System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制.其函数原型是: public static void arraycopy(Object src, int sr ...
- java数组复制的简单方法(一)
总结:主要是用a数组的长度等于b数组,然后a数组赋值给b数组,我不能想到这个办法,我还是不理解数组中length属性的含义 这里数组并没有正真复制过来,而是一个引用 package com.a; // ...
- java数组复制===clone()
总结:使用方法原理弄清楚 package com.a; public class gjsopb { public static void main(String[] args) { int a[] = ...
- Java 数组的三种创建方法,数组拷贝方法
public static void main(String[] args) {//创建数组的第一种方法int[] arr=new int[6];int intValue=arr[5];//Syste ...
- JAVA 数组算法(复制、查找、插入)
一.复制数组算法 //数组复制算法 public class Test{ public static void main(String[] args){ int[] arrA = {100,800,5 ...
随机推荐
- SpringBoot系列十:SpringBoot整合Redis
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ...
- Github 上 Star 最多的个人 Spring Boot 开源学习项目
2016年,在一次技术调研的过程中认识到了 Spring Boot ,试用之后便一发不可收拾的爱上它.为了防止学习之后忘记,就在网上连载了 Spring Boot 系列文章,没想到这一开始便与 Spr ...
- 让linux启动更快的方法
导读 进行 Linux 内核与固件开发的时候,往往需要多次的重启,会浪费大把的时间. 在所有我拥有或使用过的电脑中,启动最快的那台是 20 世纪 80 年代的电脑.在你把手从电源键移到键盘上的时候,B ...
- iview库表table组件内嵌套Select组件
表格内render函数渲染Select组件 { title: '属性值', key: 'values', render:(h,params)=>{ return h('Select',{ ...
- Shell命令-线上查询及帮助之man、help
线上查询及帮助 - man.help 1.man:获取命令的帮助信息 man命令的简单介绍 man命令是Linux系统中最核心的命令之一 ,因为通过它可以查看其它Linux命令的使用信息.当然了 ,m ...
- mysql-笔记--增删改查
查看数据库:可以使用 show databases; 命令查看已经创建了哪些数据库 指定数据库:在登录后使用 use 语句指定, 命令: use 数据库名;要对一个数据库进行操作, 必须先选择该数据库 ...
- OOM实例
1. 使用Executors.newFixedThreadPool()方法,当不断创建新任务,而任务执行速度比创建速度慢时,任务对象就会在任务队列里面排队,堆内存得不到释放,导致OOM: 2. 使用P ...
- Docker 删除容器日志
在使用docker的时候,我们经常通过 docker logs -f containername或者id 但是有时候日志很多.很麻烦.所以需要清理一下对应container的日志. 默认情况下,dao ...
- BZOJ4621 Tc605(动态规划)
容易发现最终序列所有数字的相对顺序不变,一个数字可能的覆盖范围由两边第一个比它大的数决定,且若不考虑次数限制所有这样的序列都可以变换得到.对于一个序列,其需要的最少变换次数显然就是覆盖了别的位置的数的 ...
- 动态dp学习笔记
我们经常会遇到一些问题,是一些dp的模型,但是加上了什么待修改强制在线之类的,十分毒瘤,如果能有一个模式化的东西解决这类问题就会非常好. 给定一棵n个点的树,点带点权. 有m次操作,每次操作给定x,y ...