- 浏览: 2189410 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
在java里面数组拷贝有几种方式:
(1)clone
(2)System.arraycopy
(3)Arrays.copyOf
(4)Arrays.copyOfRange
下面分别介绍下他们的用法:
(1)clone方法是从Object类继承过来的,基本数据类型(String,boolean,char,byte,short,float,double.long)都可以直接使用clone方法进行克隆,注意String类型是因为其值不可变所以才可以使用。
Int类型示例:
```` ` int a1[]={1,3}; int a2[]=a1.clone(); a1[0]=666; System.out.println(Arrays.toString(a1));//[666,3] System.out.println(Arrays.toString(a2));//[1,3] ````
String 类型示例
```` ` String[] a1={"a1","a2"}; String[] a2=a1.clone(); a1[0]="b1";//更变a1元素的值 System.out.println(Arrays.toString(a1));//[b1,a2] System.out.println(Arrays.toString(a2));//[a1,a2] ````
(2)System.arraycopy方法是一个本地的方法,源码里定义如下:
```` public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); ````
参数含义:
(原数组,原数组的开始位置,目标数组,目标数组的的开始位置,拷贝的个数)
用法示例:
```` ` int a1[]={1,2,3,4,5}; int a2[]=new int[10]; System.arraycopy(a1,1,a2,3,3); System.out.println(Arrays.toString(a1));//[1, 2, 3, 4, 5] System.out.println(Arrays.toString(a2));//[0, 0, 0, 2, 3, 4, 0, 0, 0, 0] ````
注意这个方法,需要我们自己new一个新的数组
(3)Arrays.copyOf底层其实也是用的System.arraycopy
源码如下:
```` public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } ````
参数含义:
(原数组,拷贝的个数)
用法示例:
```` ` int a1[]={1,2,3,4,5}; int a2[]=Arrays.copyOf(a1,3); System.out.println(Arrays.toString(a1));//[1, 2, 3, 4, 5] System.out.println(Arrays.toString(a2));//[1, 2, 3] ````
这个方法不需要我们new新的数组
(4)Arrays.copyOfRange底层其实也是用的System.arraycopy,只不过封装了一个方法
参数含义:
(原数组,开始位置,拷贝的个数)
用法示例:
```` ` int a1[]={1,2,3,4,5}; int a2[]=Arrays.copyOfRange(a1,0,1); System.out.println(Arrays.toString(a1));//[1, 2, 3, 4, 5] System.out.println(Arrays.toString(a2));//[1] ````
最后需要注意的是基本类型的拷贝是不影响原数组的值的,如果是引用类型,就不能这用了,因为数组的拷贝是浅拷贝。
那么如何实现对象的深度拷贝呢?
(1)实现Cloneable接口,并重写clone方法,注意一个类不实现这个接口,直接使用clone方法是编译通不过的。
```` public class Dog implements Cloneable { private String id; private String name; //省略getter / setter @Override public Dog clone() throws CloneNotSupportedException { Dog dog=(Dog) super.clone(); return dog; } } ````
示例:
```` ` Dog d1=new Dog("1","dog1"); Dog d2=d1.clone(); d1.setName("dog1_change"); System.out.println(d1);//Dog{id='1', name='dog1_change'} System.out.println(d2);//Dog{id='1', name='dog1'} ````
(2)如果一个类里面,又引用其他的类,其他的类又有引用别的类,那么想要深度拷贝必须所有的类及其引用的类都得实现Cloneable接口,重写clone方法,这样以来非常麻烦,简单的方法是让所有的对象实现序列化接口(Serializable),然后通过序列化的方法来深度拷贝对象。
```` public Dog myclone() { 6 Dog dog = null; 7 try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝 8 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 9 ObjectOutputStream oos = new ObjectOutputStream(baos); 10 oos.writeObject(this); 11 // 将流序列化成对象 12 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 13 ObjectInputStream ois = new ObjectInputStream(bais); 14 dog = (Dog) ois.readObject(); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } catch (ClassNotFoundException e) { 18 e.printStackTrace(); 19 } 20 return dog; 21 } ````
总结:
本文介绍了关于Java里面的数组拷贝的几种方式和用法,并给出了如何在Java里面实现对象的深度拷贝,注意除非必需,一般情况下不要使用对象的深度拷贝,因为性能较差。除了自己实现深度拷贝的功能外,网上也有一些开源的工具类也集成了这些功能,如Apache Common Lang3,但原理都大同小异,感兴趣的同学可以自己去学习下。
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。
发表评论
-
记一次log4j不打印日志的踩坑记
2019-09-22 01:58 1590### 起因 前几天一个跑有java应用的生产集群(200多 ... -
在Java里面如何解决进退两难的jar包冲突问题?
2019-07-23 19:10 1255如上图所示: es api组件依赖guava18.0 ... -
如何轻松理解二叉树的深度遍历策略
2019-07-03 23:33 1152我们知道普通的线性数据结构如链表,数组等,遍历方式单一 ... -
为什么单线程Redis性能也很出色
2019-01-21 18:02 2224高性能的服务器,不一 ... -
如何将编程语言里面的字符串转成数字?
2019-01-11 23:23 2112将字符串转成数字在很 ... -
为什么Java里面String类是不可变的
2019-01-06 18:36 1684在Java里面String类型是不可变对象,这一点毫无疑问,那 ... -
关于Java里面volatile关键字的重排序
2019-01-04 18:49 1087Java里面volatile关键字主 ... -
多个线程如何轮流打印ABC特定的次数?
2018-12-11 20:42 6064之前的一篇文章,我给 ... -
聊聊Java里面的引用传递
2018-11-16 21:21 992长久以来,在Java语言里面一直有一个争论,就是Java语言到 ... -
理解计数排序算法的原理和实现
2018-10-11 10:03 2097计数排序(Counting sort) ... -
理解Java7和8里面HashMap+ConcurrentHashMap的扩容策略
2018-09-06 11:31 3394### 前言 理解HashMap和Con ... -
关于Java里面多线程同步的一些知识
2018-07-18 09:45 1111# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
Java单例模式之双检锁深入思考
2018-07-08 12:25 3298# Java单例模式之双检锁 ... -
关于Java里面多线程同步的一些知识
2018-07-08 12:23 1124# 关于Java里面多线程同步的一些知识 对于任何Java开 ... -
重新认识同步与异步,阻塞和非阻塞的概念
2018-07-06 14:30 1476# 重新认识同步与异步 ... -
线程的基本知识总结
2018-06-27 16:27 1063### (一)创建线程的方式 (1)实现Runnable接口 ... -
Java里面volatile关键字修饰引用变量的陷阱
2018-06-25 11:42 1390# Java里面volatile关键字修饰引用变量的陷阱 如 ... -
关于Java里面的字符串拼接,你了解多少?
2018-06-25 11:28 1376# 关于Java里面的字符串 ... -
深入理解Java内存模型的语义
2018-06-25 11:39 745### 前言 Java内存模型( ... -
如何证明Java多线程中的成员变量数据是互不可见的
2018-06-21 10:09 1509前面的几篇文章主要介绍了Java的内存模型,进程和线程的定义, ...
相关推荐
首先,我们要知道在C#中,有几种不同的方法可以实现数组拷贝: 1. **Array.Copy()**:这是.NET框架提供的一个静态方法,用于从源数组的一部分复制到目标数组中。这种方法适用于不同类型的数组,只要它们的元素类型...
有几种不同的方法可以实现数组的复制,每种方法都有其特定的适用场景。以下将详细阐述Java中复制数组的主要方法: 1. **浅拷贝(Shallow Copy)**: - `System.arraycopy()`:这是Java中最直接、最高效的方式来...
Java是一种广泛使用的编程语言,以其跨平台、面向对象的特点深受开发者喜爱。本教程将深入探讨Java中的数组、方法以及面向对象编程的基础概念,为初学者提供一个全面的学习指南。 一、数组 数组在Java中是存储同一...
本文将围绕Java数组进行详细介绍,并辅以示例来加深理解。 首先,我们要了解数组的访问机制。数组是一种线性数据结构,其元素通过整数索引进行访问。数组在声明时需要指定元素类型和数组大小,一旦创建完成,其长度...
数组操作还包括数组拷贝,如使用`System.arraycopy()`方法,或利用`java.util.Arrays`类提供的工具方法。例如,打印数组内容: ```java int[] a = {1, 2}; System.out.println(Arrays.toString(a)); // [1, 2] ``` ...
下面,我们将详细讨论Java数组的相关知识点。 1. **数组定义**:数组是由相同类型的元素序列组成的复合数据类型。在Java中,我们可以通过以下方式声明数组: ```java 数据类型[] arrayName; 或 数据类型 ...
在编程世界中,数组是一种非常基础且重要的数据结构,它允许我们存储一组相同类型的数据。在函数调用中,有时我们需要传递多个值给一个函数,这时数组参数就显得尤为重要。本学习内容主要聚焦于“数组参数”,让我们...
首先,我们要了解在Java中,有几种类型的数组可供选择:一维数组、二维数组以及多维数组。在Android开发中,主要是使用Java语言,所以这里主要讨论Java中的数组。 1. 一维数组: 一维数组是最基本的数组形式,可以...
Java数组的大小受到`int`类型的限制,因为数组的索引是`int`类型。这意味着最大数组大小不能超过`Integer.MAX_VALUE`(2^31 - 1),约2GB。但你可以创建更大元素类型(如`long`)的数组,即使这样可能会导致实际...
在"java代码-lsy数组比"这个主题中,我们可以推测这可能是关于比较或操作Java数组的一些代码示例。让我们深入探讨一下Java中的数组以及可能涉及的概念。 1. **数组定义与声明**: 在Java中,数组的定义包括指定...
在Java中,拼接`byte`数组可以通过以下几种方式实现: 1. **使用`System.arraycopy()`**: 这是Java中最常用的方法,它可以从源数组中复制指定范围的元素到目标数组中。例如,假设我们有两个`byte`数组`arr1`和`...
在Java中实现深拷贝,我们可以有以下几种方法: 1. **实现Serializable接口**:这是通过序列化和反序列化实现深拷贝的方法。首先将对象转换为字节数组,然后从这个字节数组中反序列化出一个新的对象。这种方法简单...
在Java编程语言中,数组是一种非常基础且重要的数据结构,特别是在大数据处理中,对大量数据的高效管理和操作离不开数组的应用。本节我们将深入探讨数组的引入和学习。 首先,数组的引入是为了解决特定问题,例如在...
Java支持以下几种数据类型: - **基本类型**:如int、float、char等。 - **引用类型**:如类、数组等。 ##### 3.5 命名规则 - 类名首字母大写。 - 变量名首字母小写。 - 方法名首字母小写,采用驼峰命名法。 ####...
Java支持以下几种基本数据类型: - **整型**:`byte`, `short`, `int`, `long` - **浮点型**:`float`, `double` - **字符型**:`char` - **布尔型**:`boolean` #### 十一、类型转换 - **隐式转换**:自动地从小...
Java提供了多个类来协助数组的操作,其中`System`类中的`arrayCopy()`方法可以用来拷贝数组,而`Arrays`类则提供了多种静态方法来操作数组,如排序、搜索等。 在处理数组时,需要注意两种常见的异常:`...
在Java中,我们可以通过以下几种方法实现对象的深拷贝: 1. **实现Serializable接口**:利用序列化和反序列化来实现深拷贝。首先将对象序列化为字节数组,然后再将这个字节数组反序列化为新的对象。这种方法适用于...
关于 null 的几种处理方式大小写敏感 null 是任何引用类型的初始值 null 只是-种特殊的值使用 Null-Safe 方法null 判断 关于思维导图 Java.IO Java.lang Java.math Java.net Java 基础核心总结 V2.0 IO 传统的 ...
在实际开发中,根据需要也可以对顺序栈进行扩展,比如增加栈的容量(数组扩容通常涉及数组拷贝),或者实现一个支持迭代的栈,以便于进行遍历操作等。此外,Java标准库中提供了`java.util.Stack`类,它也是基于数组...
**5.5 数组拷贝** - 可以使用`System.arraycopy()`方法或者`Arrays.copyOf()`方法来复制数组。 #### 六、对象和类 **6.1 面向对象与面向过程** - **面向对象**:将数据和操作数据的方法封装在一起。 - **面向...