List
<
String
>
a
=
new
ArrayList
<
String
>
(
10000000
)
;
int
i
=
1
;
for
(
int
x
=
1
;
x
<
10000000
;
x
=
x
+
1
)
{
a
.
add
(
Integer
.
toString
(
x
)
)
;
List
<
String
>
b
=
new
ArrayList
<
String
>
(
10000000
)
;
List
<
String
>
c
=
new
ArrayList
<
String
>
(
10000000
)
;
long
begintime
=
System
.
nanoTime
(
)
;
b
=
(
List
<
String
>
)
(
(
ArrayList
<
String
>
)
a
)
.
clone
(
)
;
明显,问题没有这么简单
深度拷贝的话最简单就是遍历,这个基本都知道,自己实现遍历性能不会是最高的,开始思考
collections包含的方法
Collections.copy(c,a);
但这种方法具有局限,List c的size 要>= a.size()
并且根据代码这种方式也是浅拷贝
接下来想,如果是List
可以使用addall()
原理是数据拷贝,使用了java的native方法复制内存
同样也是浅拷贝
经过对比集中浅拷贝
java中提供了流式计算
d = a.stream().collect(Collectors.toList());
经过实际验证:
addall()和collections.copy(a,b)
消耗时间接近,是比较好的复制方法,其中addall()略微好于collections
一般java的高效的集合类都在
java.util.concurrent.*;
分析代码:
long begintime5 = System.nanoTime();
CopyOnWriteArrayList m=new CopyOnWriteArrayList(a);
long endtime5 = System.nanoTime();
long costTime5 = (endtime5 - begintime5)/1000;
System.out.println("测试结束5: "+costTime5);
底层原理分析,看代码
* Creates a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
* @param c the collection of initially held elements
* @throws NullPointerException if the specified collection is null
public CopyOnWriteArrayList(Collection<? extends E> c) {
Object[] elements;
if (c.getClass() == CopyOnWriteArrayList.class)
elements = ((CopyOnWriteArrayList<?>)c).getArray();
else {
elements = c.toArray();
if (elements.getClass() != Object[].class)
elements = Arrays.copyOf(elements, elements.length, Object[].class);
setArray(elements);
这段显示,调用了Arrays.copuOf()
* Copies the specified array, truncating or padding with nulls (if necessary)
* so the copy has the specified length. For all indices that are
* valid in both the original array and the copy, the two arrays will
* contain identical values. For any indices that are valid in the
* copy but not the original, the copy will contain <tt>null</tt>.
* Such indices will exist if and only if the specified length
* is greater than that of the original array.
* The resulting array is of the class <tt>newType</tt>.
* @param <U> the class of the objects in the original array
* @param <T> the class of the objects in the returned array
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @param newType the class of the copy to be returned
* @return a copy of the original array, truncated or padded with nulls
* to obtain the specified length
* @throws NegativeArraySizeException if <tt>newLength</tt> is negative
* @throws NullPointerException if <tt>original</tt> is null
* @throws ArrayStoreException if an element copied from
* <tt>original</tt> is not of a runtime type that can be stored in
* an array of class <tt>newType</tt>
* @since 1.6
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;
接下来调用了
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
看看最后:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
java的native 方法,效率最高
本质和collection的clone的方法逻辑一致
集合的深度拷贝,除了遍历还有一种是序列化和反序列,这种首先排除在外,接下来看看还有没有其他方式
查询了资料,木有发现更好的深拷贝方法
经过实践对比,序列化、反序列化是效率最高的办法
public static <T> List<T> depCopy(List<T> srcList) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
try {
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(srcList);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream inStream = new ObjectInputStream(byteIn);
List<T> destList = (List<T>) inStream.readObject();
return destList;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
以上针对问题,初步研究。
参考1:https://blog.csdn.net/u010648159/article/details/79144154
参考2:https://blog.csdn.net/demonliuhui/article/details/54572908
文章目录Lsit中数据复制问题1.1copy问题1.2怎么高效的复制1.3 回答Lsit中数据复制问题这是由一道开放式面试题引发的文章,题目:加入内存足够大,一个集合中有100万条数据,怎么高效的把集合中的数据复制到另外一个集合1.1copy问题java 中复制分为浅拷贝和深拷贝如果考察浅拷贝:直接使用clone方法System.out.println("测试开始时");...
在 Vue.js 中,可以使用 JavaScript 数组的 slice() 方法复制一个数组的数据到另一个数组中。例如:
let list1 = [1, 2, 3, 4, 5];
let list2 = list1.slice();
也可以使用 JavaScript 的 spread 运算符:
let list1 = [1, 2, 3, 4, 5];
let list2 = [...list1...
背景:现在有一个字段非常多大实体类1构成的集合一,另一个集二合中的实体类2需要集合一中的部分属性,所以需要进行属性的复制。
基础类一:作为复制的源头
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
在Java开发中,有时候我们为了源List集合的数据不被修改,如果采用类似“new_list = old_list”这种形式来复制克隆一个新的List集合是绝对不行的,所以我们得采用下面的三种方法来复制一个新的List集合。
Java克隆复制ArrayList等List集合的方法一:
Java中克隆复制一个List可以在创建List对象时通过将源List集合以参数的形式传入即可,代码如下:importjava.util.ArrayList;
importjava.util.Arrays;
importjav
Java将一个集合中数据复制或赋值到另一个集合数据中添加到一个集合
public static void main(String[] args)throws Exception {
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2");
list1.add("3");
list1.add("5")
可以使用addAll()方法将一个集合中的所有元素添加到另一个集合中,从而实现合并两个集合的数据。例如:
List<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
List<String> list2 = new ArrayList<>();
list2.add("c");
list2.add("d");
list1.addAll(list2);
System.out.println(list1); // 输出 [a, b, c, d]