今天在使用ArrayList的时候遇到一个问题,搞了快一个钟头才知道怎么回事,这都是没有好好看API的结果。ArrayList相当于数组的作用,按顺序存放一系列数据,存放的类型可以为任意类型,常用的方法都在API中很好理解,大家可以查看API。
关于复制Java的API中有这样一句话:
.clone()
Returns a shallow copy of this ArrayList instance.
这说明ArrayList 是一种浅表拷贝,只是拷贝表层数据。
但是,到底什么是表层数据的拷贝呢?
看到网上一个例子很贴切:
就好比一个爸爸一个儿子
浅拷贝:你克隆一下,只得到一个爸爸,这是浅
深拷贝:你克隆一下,既得到了爸爸,又得到了儿子,这是深
也就是说如果ArrayList<E>中:
E如果是一个基本数据类型,使用clone()拷贝,能够实现拷贝一个新的值。
但是,如果E是一种复合类型,例如是个类,那么.clone()只是实现了对一个对象引用的拷贝,这个拷贝的ArrayList仍然同原来的ArrayList指向内容相同,一个变了,另一个也跟着变了,并没有实现真正意义上的拷贝,所以所以是一种浅拷贝。
实现ArrayList 深拷贝的方法:(在网上借的)
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;
}
}
也就是把ArrayList的原来的对象进行序列化,之后在进行反序列化读取出来。
因此,使用这种深拷贝方法必须满足集合中的元素能够序列化,必须实现Serializable接口。
分享到:
相关推荐
7. 其他操作:还包括CopyTo方法,可以将ArrayList复制到一个数组,以及ToArray方法,可以将ArrayList转换为同类型的数组。 然而,随着.NET Framework的演进,ArrayList逐渐被泛型集合,特别是List所取代。List提供...
- 避免频繁地执行增加和删除操作,因为这些操作可能导致底层数组的复制,从而影响性能。 8. **示例代码** 下面是一个简单的示例,演示了如何使用`ArrayList`: ```csharp ArrayList list = new ArrayList(); ...
- **增长策略**:当元素数量达到数组容量极限时,ArrayList会创建一个新的更大容量的数组,并将旧数组的所有元素复制到新数组中。这个过程称为扩容。为了减少频繁的扩容操作,可以在创建ArrayList时指定初始容量或...
- `CopyTo`方法将ArrayList复制到一个数组中。 - `TrimToSize`方法将`Capacity`调整为实际的`Count`值,节省内存。 4. 使用建议: - 尽管ArrayList在早期版本的.NET框架中广泛使用,但在.NET 2.0及更高版本中,...
- `Collections.sort()`方法会改变原ArrayList的顺序,如果不想改变原集合,可以先复制一份ArrayList再进行排序。 - 对于大量数据的排序,ArrayList的性能可能不如使用LinkedList,因为ArrayList排序时涉及到大量...
- 扩容通常涉及创建一个新的更大的数组,并将旧数组中的所有元素复制到新数组中。 - 默认的扩容策略是将当前容量翻倍,但这可以通过重写`ArrayList`类来调整。 5. **同步性问题**: - `ArrayList`自身不提供任何...
- CopyTo方法:将ArrayList复制到一个新的数组或已存在的数组中。 总的来说,ArrayList在C#中是一个常用的集合类,尤其适合于需要动态扩展数组大小且对性能要求不高的场景。然而,随着.NET Framework的演进,更推荐...
4. **安全性问题**:在传递ArrayList到方法或作为返回值时,如果不希望外部修改ArrayList,可以使用`Collections.unmodifiableList()`将ArrayList转换为不可变的视图,或者在方法内部复制一份ArrayList后再进行操作...
浅析ArrayList内部实现 ArrayList是Java集合框架中的一种常用数据结构,能够存储任意多个对象,并且可以自由扩展,弥补了数组的定长的缺陷。下面我们将深入探讨ArrayList的内部实现机理。 ArrayList的内部实现机理...
当添加元素时,如果当前容量不足以容纳新元素,ArrayList就会创建一个新的更大的数组,并将旧数组中的所有元素复制到新数组中,这个过程称为自动扩容。 对于ArrayList的同步性,需要注意的是,它并不是线程安全的。...
- `CopyTo(Array array, int index)`: 将ArrayList复制到一个数组中。 2. Stack:栈是一种后进先出(LIFO)的数据结构,常用于临时存储和恢复数据。Stack的主要操作有: - `Push(object item)`: 将元素压入栈顶。...
然而,插入和删除操作可能涉及到数组的复制和移动,效率相对较低。 2. 动态扩容:当ArrayList中的元素数量超过其当前容量时,它会自动扩容,通常会将容量翻倍,以确保能够继续添加元素。这个过程虽然保证了...
- **构造器**:ArrayList提供了三个构造器,分别是无参构造器(默认容量16)、接受ICollection参数的构造器(将集合元素复制到ArrayList)以及接受初始容量整数的构造器。 - **IsSynchronized属性和Synchronized...
当数组容量不足时,`ArrayList`会创建一个新的更大容量的数组,并将原有元素复制到新数组中。 2. **随机访问**:由于`ArrayList`底层基于数组实现,因此可以快速通过索引访问元素,时间复杂度为O(1)。这使得`...
- 从 Collection 构造:`ArrayList(ICollection c)`,复制集合中的元素到 ArrayList。 - **IsSynchronized 属性**:表明 ArrayList 是否线程安全。若非线程安全,需手动使用 `synchronized` 关键字进行同步控制。 ...
grow方法是ArrayList实际增长容量的实现,它会在添加元素而数组容量不足时被调用,通过新建一个更大容量的数组并将原数组复制过去来实现扩容。 除了上述直接与ArrayList初始化和扩容相关的方法,ArrayList类还定义...
ArrayList提供了诸如Add、Insert、Remove、Clear等方法,这些操作可能涉及到对内部数组的重新分配和复制,如果没有正确同步,多个线程同时进行这些操作可能导致数据损坏。例如,当一个线程正在添加元素并导致数组...
ArrayList是我们经常会用到的集合类,有时候我们需要拷贝一个ArrayList,今天向大家介绍拷贝ArrayList常用的四种方式。 使用构造函数 ArrayList有个构造函数,可以传入一个集合: public ArrayList(Collection c) {...
这个过程涉及到数组的复制,是ArrayList的一个重要性能考虑点。 ArrayList的增删改查操作主要依赖于其底层的数组。添加元素(add)时,如果数组还有空位,则直接插入;否则,进行扩容并复制元素。删除元素(remove...
ArrayList在添加元素时,如果数组已满,会创建一个新的更大的数组,并将旧数组中的元素复制到新数组中,然后在新数组的末尾添加新元素。 ```java public void add(T element) { if (size == elements.length) { ...