java addall是java map 深拷贝贝吗

本人在设计数据库缓存层的时候,需要对数据进行深拷贝,这样用户操作的数据对象就是不共享的。
这个思路实际上和Erlang类似,就是用数据不共享解决并发问题。
1. 序列化?
原来的做法,是用序列化,我用了Json的序列化,lib-json。一个再传统不过的方法。把数据字段序列化成json保存。取出来的时候进行反序列化。
测试100条数据,100次循环,竟然TM的用了15秒。
这个是个啥概念?简直惨不忍睹。
于是网上搜,找到个Jackson,号称性能XXX的,比Google的gson高XXX。
替换之后,速度下降到3700ms。恩。有那么点意思。
但是才100次全查询,消耗了接近4秒,不可接受。
为什么不直接序列化?因为我设计表结构是变动的,使用json的key-value很容易进行表结构的扩展伸缩。
gson这货,竟然一步到位把json字符串转化成了对象。我只能说,太over-architecture了。过分的api设计了。
jackson使用了JsonNode,本质还是键值对,这种恰到好处的设计,非常方便。
如果要使用json, json-lib就是一坨屎,简直就是实验室作品。。。用jackson吧。
2. Cloneable接口?
我一向有个观点,Java提供的原生API性能一定比自己无论怎么搞也高效。
很可惜,Cloneable接口第一,没有public object clone。不知道他搞什么飞机。继承接口还不是public的。要自己调用object.clone. 第二,是浅拷贝,如果有对象数组,还是指针引用。
Usr_Equipment implements CLoneable
  @Override
  public Object clone() { super.clone();}}
可惜了,真心不知道这个Cloneable设计出来是干什么的。
于是自己设计一个ICloneable extends Cloneable接口,把clone暴露出来。
3. 浅拷贝变成深拷贝?
为了实现深拷贝,必然需要使用递归对整个对象的属性遍历。整个魔法的核心,就是BeanCopier。性能比BeanMap更强大!我先放出代码:
package mon.
import java.lang.reflect.A
import java.util.concurrent.ConcurrentHashM
import java.util.concurrent.ConcurrentM
import net.sf.cglib.beans.BeanC
import net.sf.cglib.core.C
import mon.interfaces.IC
import mon.tool.ParserH
public class CloneableBase implements ICloneable
private static ConcurrentMap&Class&?&, BeanCopier& beanCopiers = new ConcurrentHashMap&Class&?&, BeanCopier&();
public Object clone()
Object clone = this.getClass().newInstance();
BeanCopier copier = _createCopier(this.getClass());
copier.copy(this, clone, new Converter()
public Object convert(Object pojo, Class fieldType, Object fieldName)
return _clone(pojo);
catch (Exception e)
throw new RuntimeException(e);
private static Object _clone(Object bean)
if (bean == null)
else if (bean instanceof ICloneable)
return ((ICloneable) bean).clone();
if (bean.getClass().isArray() && !bean.getClass().getComponentType().equals(byte.class))
int length = Array.getLength(bean);
Object clone = Array.newInstance(bean.getClass().getComponentType(), length);
for (int i = 0; i & i++)
Array.set(clone, i, _clone(Array.get(bean, i)));
private static BeanCopier _createCopier(Class&?& clz)
if (beanCopiers.containsKey(clz))
return beanCopiers.get(clz);
beanCopiers.putIfAbsent(clz, BeanCopier.create(clz, clz, true));
return beanCopiers.get(clz);
上面就是整个深拷贝的魔法核心。
1)使用了BeanCopier,并缓存这个对象,性能提升50%,从1s下降到600ms。
2)判断array,如果是byte[]类型,直接使用浅拷贝。这个是个特殊对象。
测试下来,比用BeanMap快2倍。相同的对象,BeanMap需要1700ms,而BeanCopier只需要500ms。
我自认为,这个方法已经做到极致了。(没测试二进制序列化)。只要自己的对象继承了CloneableBase,就能够实现深度拷贝。
阅读(...) 评论()关于arrayList的add和addall - CSDN博客
关于arrayList的add和addall
花了一周时间,重构了系统中最重要的一段下发打印逻辑的代码,理清了各类型间的调用关系,得意之际,测试告诉代码数据异常了,花了5个小时的测试,终于发现了问题,用错了ArrayList的addAll方法,下面列举下add和addAll方法。
ArrayList是一个实现可变长数组,继承AbstractList类,实现所有的List接口,还实现了RandomAccess、Cloneable、Serializable接口。
add源代码:
&&& public boolean add(E e) {
&&&&&&& ensureCapacityInternal(size + 1);
&&&&&&& elementData[size++] =
addAll源代码:
&& //将Collection c内的数据插入ArrayList中
&& public boolean addAll(Collection&? extends E& c) {
&&&&&&& Object[] a = c.toArray();
&&&&&&& int numNew = a.
&&&&&&& ensureCapacityInternal(size + numNew);& // Increments modCount
&&&&&&& System.arraycopy(a, 0, elementData, size, numNew);
&&&&&&& size += numN
&&&&&&& return numNew != 0;
&&& //将Collection c中的数据插入到ArrayList的指定位置
&&& public boolean addAll(int index, Collection&? extends E& c) {
&&&&&&& rangeCheckForAdd(index);
&&&&&&& Object[] a = c.toArray();
&&&&&&& int numNew = a.
&&&&&&& ensureCapacityInternal(size + numNew);& // Increments modCount
&&&&&&& int numMoved = size -
&&&&&&& if (numMoved & 0)
&&&&&&&&&&& System.arraycopy(elementData, index, elementData, index + numNew,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& numMoved);
&&&&&&& System.arraycopy(a, 0, elementData, index, numNew);
&&&&&&& size += numN
&&&&&&& return numNew != 0;
可以看出,add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素,而addAll是传入一个List,将此List中的所有元素加入到当前List中,也就是当前List会增加的元素个数为传入的List的大小
本文已收录于以下专栏:
相关文章推荐
下面的示例演示java.util.Arraylist.addall(c) 方法的用法。
package com.
import java.util.ArrayL
package com.robot.
import java.util.ArrayL
public class TestCode {
public static void ma...
问题是这样产生的ListA 里面有  1   2    3  ListB里面有  4    5   6  让ListA变成  1  2&#1...
我们在编码时经常需要将一些元素添加到一个List中,此时我们一般有两种选择:Collections.addAll()或者是ArrayList.addAll()。在需添加元素比较少的情况下,并在List...
转自:http://blog.csdn.net/phenix_egg/article/details/
ArrayList是一个实现可变长数组,继承Abstrac...
add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素addAll是传入一个List,将此List中的所有元素加入到当前List中,也就是当...
set:将原来index位置上的object的替换掉
add:将原来index位置上的向后移动
今天在开发项目的过程中,准备使用ArrayList 的 add(index,element) 来插入元素,天真的以为这样能给list排序
简略代码如下:
List li...
今天写代码,遇见一个问题:
   File fileinfo=new File();
   ArrayList list=new ArrayList();
  
   FileStatu...
1:大体思路
  
这种转换要用到java.text.SimpleDateFormat类
字符串转换成日期类型:
也是最简单的方法 Date date=new Date(...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)arrayList addAll方法使用 - CSDN博客
arrayList addAll方法使用
ListA 里面有& 1&& 2&&& 3&
ListB里面有& 4&&& 5&& 6&
让ListA变成& 1& 2& 3& 4& 5& 6&&
我觉得很简单 ,就说用for循环遍历 添加就好了。结果面试官说
答案是使用addAll方法,因为这样效率高:
我表示很费解,于是查阅了资料。
得出以下结论:
在小数据量时,for循环效率高,大数据量时addAll方法效率高:
原因如下:
ArrayList的addAll的实现为:&
很显然。。在拷贝数组时使用了
arraycopy 这个方法。这个方法是使用拷贝内存的做法 ,效率比遍历数组块很多。
首先找到数据源 然后将该段内存拷贝。
当然值得注意的是,这个函数中还使用了toArray方法,这个方法是 要遍历操作的
但是如果需要多次遍历,那么addAll还是在性能上会获取优势的. .
下面是网上的一个测试 在20组数据时 还是 for效率高,但是在大数据量的时候 arraycopy 方法就明显占优势了。
arraycopy的定义是这样的
public static native void arraycopy(Object src,& int& srcPos, Object dest, int destPos,int length);
native关键字的意思是 这个函数的源码在JDK中没有的。但是他调用的是本地计算机中的函数
这个函数是C,或者C++写完的,编译成DLL。 java调用。所以效率比for循环要块。
综上所述 :为什么在大数据量时使用addall方法效率快?
1.使用内存拷贝,移动数据。
2.本地函数,执行效率高。
那小数据量时呢?
以上2点都不明显,并且首先要调用toArray方法,在小数据量时,效果没有for来的好。
本文已收录于以下专栏:
相关文章推荐
问题是这样产生的ListA 里面有  1   2    3  ListB里面有  4    5   6  让ListA变成  1  2&#1...
采摘处:/java/1752.html
addAll(Collection col)方法用来将指定集合中的所有对象添加到该集合中。如果对该集合...
在做项目时我遇到过这样的问题,java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.alibaba.gette...
采摘处:http://blog.csdn.net/sutaizi/article/details/6607123
问题是这样产生的,网上一哥们发了一个面试题:
ListA 里面有  1...
1、什么是ArrayList
    ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处:
动态的增加和减少元素实现了ICollecti...
1. ArrayList概述:
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, Random...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)java list.addAll方法的一些使用记录 - CSDN博客
java list.addAll方法的一些使用记录
今天做同步排序的时候,要对所有的record进行相应的处理然后排序实现ZAKER中的某些功能,使用到LIst.addAll方法,但是不懂addall是浅拷贝还是深拷贝,于是写demo测试;
结果:List list1; &List list2; & list1.addAll(list2);对于两list而言,进行的是深拷贝,即对list2进行clear不会影响list1;但是若list里面存放的是自定义的类的时候,该类型实现了序列化接口,对于该自定义的类进行的确实浅拷贝,也就是说,当执行addAll操作后,对list2中的数据进行修改也会影响到list1的数据;
本文已收录于以下专栏:
相关文章推荐
List引用一
ListPerson& persons = PersonService.getPersonsByAgeIn(18,23);//初始化一个Person的List。  
ListPer...
集合合成的话List list1 = new ArrayList();  /*.....添加数据.......*/List list2 = new ArrayList();  /*.....添加数据....
在做项目时我遇到过这样的问题,java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.alibaba.gette...
Collection result = new ArrayList();
Collection list = new ArrayList();
result.addAll(li...
问题是这样产生的,网上一哥们发了一个面试题:
ListA 里面有  1   2    3 
ListB里面有  4    5   6 
add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素
addAll是传入一个List,将此List中的所有元素加入到当前Lis...
package com.wp.
import java.util.ArrayL
import java.util.C
import java.util...
昨天项目中遇到了一个将查询结果增量发出的,即每次比上次增的获取。
这个问题同事去网上找了好多高人写的代码,我看了好久,感觉被绕了,最后想着还是用最简单的方式来做,可能好一些。
package co...
问题是这样产生的ListA 里面有  1   2    3  ListB里面有  4    5   6  让ListA变成  1  2&#1...
采摘处:/java/1752.html
addAll(Collection col)方法用来将指定集合中的所有对象添加到该集合中。如果对该集合...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Java中关于list的深拷贝与浅拷贝 - CSDN博客
Java中关于list的深拷贝与浅拷贝
这两天在写作业,被list复制的问题卡住了,想实现深拷贝效果却总是浅拷贝,网上查了些资料,总结了一下这个问题,以后避免再走弯路。
1. 深拷贝与浅拷贝的概念
(1)深拷贝:
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原
有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
(2)浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不
复制它所引用的对象。
一句话总结,就是复制后产生的对象改变了会影响原来的对象即是浅拷贝,不会影响原来的对象即是深拷贝。
2. java中浅拷贝的方法
&&这里给出了java中浅拷贝的方法,包括遍历复制,构造一个新的list,addall等方法。
事实上,以上这些方法在一些情况下可以实现深复制,前提是list中的元素必须是基本类型。如果list中的元素是对象或者是其他list,那么实现的效果只能是浅拷贝。
3. java中深拷贝的方法
(1)递归方法
& & & &&&这里给出了多层list情况下的递归方法。实测有效。可以看出必须把待复制的对象扒成基本类型后才能复制。
(2)序列化方法
& & & &上面两个链接中都给出了序列化的方法,由于没学过还看不太懂,姑且记下,以后再说。
PS:以前忘记在哪看到的一句话,大意是说java中基本类型传值,对象传引用,看来是正确的。
本文已收录于以下专栏:
相关文章推荐
List浅拷贝众所周知,list本质上是数组,而数组的是以地址的形式进行存储。
如上图将list A浅拷贝给list B,由于进行的是浅拷贝,所以直接将A的内容复制给了B,java中相同内容的数组指向...
本文整合量两篇文章,简要概括
由于addAll()实现的是浅拷贝,即将
List A& copy=new ArrayList A&();
List A& src=new ArrayList A&();
package com.wp.
import java.util.ArrayL
import java.util.C
import java.util...
前言:       日前一哥们问我一个有关多层ArrayList拷贝的问题,我帮他写了一个例程,感觉以后用得着,便放上来了。如果要在自身类中加入Clone功能,需要implements IClonea...
之前探讨过Java数组的深复制问题,现在来说说。为什么不说呢?因为在寻找探索的过程中,我发现了这些不靠谱的方法,写下来是希望给自己和他人提个醒,不要犯这样的错误。
这是下面要频繁使用的...
public static void  main(string[]  args)
     int[] arrayInt=new int[] {1,2,3,4,5}
   &#16...
#声明和实例化
声明:ArrayList a, 仅仅只是声明了一个list变量,其未来作用相当于C++中的引用变量,亦或者相当于一个对象块的索引,但并未为其分配具体的完整的对象所需要的内存空间,其所...
Fragment 的两种创建方式
看了许多关于app2sd的帖子,里面都不可避免的涉及到mount命令的使用,但大多知其然不知其所以然,新手
看上去难免一头雾水,鉴于这是一条比较危险的命令,
这里对于mount命令进行一次详解。
...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 java数组深拷贝 的文章

 

随机推荐