关于arraylist的一个神坑之add方法

ArrayList acsdatas = new ArrayList<>();
for(Map.Entry entry:channelmap.entrySet()) {
Acsdata acsdata = new Acsdata();
if (!StringUtils.isEmpty(entry.getKey())) {
//此时说明该通道存在并且处于活跃中
acsdata.setAcsstatue(true);
Session session = entry.getValue();
acsdata.setAcsagreement(baseServer.getDisplayName());
acsdata.setAcsdatatype(baseServer.getDatetype());
//获取接入时间
acsdata.setAcstime(Long.toString(session.getLastCommunicateTimeStamp()));
setChannel(session.getChannel());
//获取服务器端口号
acsdata.setServerport(getport(channel.localAddress().toString()));
//获取客户端地址
acsdata.setAcsip(getip(channel.remoteAddress().toString()));
//获取客户端端口
acsdata.setAcsport(getport(channel.remoteAddress().toString()));
if (channelandMN.getInstance().getmap(session.getId()).toString()!=null) {
//获取MN编号
            acsdata.setAcsMN(channelandMN.getInstance().getmap(session.getId()).toString());
}else {
    //此时通道已建立,但还未发送数据。因此无法分析数据获取MN编号存储进redis,此处无法从redis获取。
log.info("此时通道已建立,但还未发送数据。因此无法分析数据获取MN编号存储进redis,此处无法从redis获取。");
}


}

acsdatas.add(acsdata);





之前为了效率觉得Acsdata 的实例化不应该放在for循环当中,因为这样的话每次都会创建一个对象。如果for魂环量大的话还是很耗费资源的,于是把它放到了循环外。结果每次循环完arraylist对象中值都是一样的,调了半天解决不了上网查了下资料,原来list的add方法添加的是对象的引用。卧槽,我也是醉了,为什么以前没遇到这种问题,于是去看以前的代码,


for (SysUserRole sysUserRole : sysUserRoles) {
if (sysUserRole.getRoleId()!=null) {
sysRole= sysRoleMapper.selectByPrimaryKey(sysUserRole.getRoleId());
sysRoles.add(sysRole);
}
}
ReturnDataInfo.setSysRole(sysRoles);


发现以前代码都是通过查询一次性把列表数据全拿过来了,怪不得不会出现引用的问题。


心想有什么办法让创建对象可以在外面呢,于是试了试linkedlist,结果还是一样的,这就没办法了,用json估计太扯了,那就先干脆这样用,在add之后回收下acsdata=null;虽然有垃圾回收机制显得多此一举,但应该也快那么一丢丢把!!!

你可能感兴趣的:(list的add方法)