1. 程式人生 > >關於arraylist的一個神坑之add方法

關於arraylist的一個神坑之add方法

ArrayList<Acsdata> acsdatas = new ArrayList<>();
for(Map.Entry<String, Session> 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;雖然有垃圾回收機制顯得多此一舉,但應該也快那麼一丟丟把!!!