专栏名称: 程序员大咖
为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等。并不定期奉送各种福利。
目录
相关文章推荐
51好读  ›  专栏  ›  程序员大咖

Java ArrayList 踩坑记录

程序员大咖  · 公众号  · 程序员  · 2017-09-27 10:24

正文

点击上方“ 程序员大咖 ”,选择“置顶公众号”

关键时刻,第一时间送达!


做编程的一个常识:不要在循环过程中删除元素本身(至少是我个人的原则)。否则将发生不可预料的问题。


而最近,看到一个以前的同学写的一段代码就是在循环过程中删除元素,我很是纳闷啊。然后后来决定给他改掉。然后引发了另外的惨案。


原来的代码是这样的:


public List getUserDebitCard(A cond) {

List list = userService.getCard(cond);

List result = null;

if(list! = null && list.size() > 0){

Collections.sort(list, new Comparator (){

public int compare(A b1, A b2) {

//按时间排序

if(Integer.valueOf(b1.getAddTime()) > Integer.valueOf(b2.getAddTime())){

return -1;

}

return 1;

}

});

A bean = getA(cond);

result = new ArrayList ();

if(bean!=null){

for (int i = 0; i < list.size(); i++) {

if(list.get(i).getCardNum().equals(bean.getCardNum())){

list.get(i).setAs(1);

result.add(list.get(i));

list.remove(i);

}else{

list.get(i).setAs(0);

}

}

}

result.addAll(list);

}

return result;

}


看了如上代码,我很是郁闷,然后给改成如下:


public List getUserDebitCard(A cond) {

List list=userService.getCard(cond);

List result=null;

if(list!=null && list.size()>0){

Collections.sort(list, new Comparator (){

public int compare(A b1, A b2) {

//按时间排序

if(Integer.valueOf(b1.getAddTime()) > Integer.valueOf(b2.getAddTime())){

return -1;

}

return 1;

}

});

A bean = getA(cond);

result=new ArrayList<>();

if(bean != null){

// 将上次的卡放置在第一位

Integer lastAIndex = 0;

Integer listSize = list.size();

if(listSize > 0) {

for (int i = 0; i < listSize; i++) {

if (list.get(i).getCardNum().equals(bean.getCardNum())) {

list.get(i).setAs(1);

result.add(list.get(i));        //将排在首位的元素先添加好,并记录下index

lastAIndex = i;

//                             list.remove(i);                //循环过程中删除元素是危险的

} else {

list.get(i).setAs(0);

}

}

list.remove(lastAIndex);

}

}

result.addAll(list);                            //在循环外删除元素,以为万事大吉,结果悲剧了,这里居然添加了两个元素进来

}

return result;

}


这下出事了,原本只有一个元素的result,现在变成了两个了,这是为什么呢?妈蛋,我明明已经remove掉了啊。


也想过百度一下,但是木有搞定啊。然后,拿出看家绝招,断点调试,进入list.remove(Integer) 方法。其源码如下:


/**

* Removes the first occurrence of the specified element from this list,

* if it is present.  If the list does not contain the element, it is

* unchanged.  More formally, removes the element with the lowest index

* i such that

* (o==null ? get(i)==null : o.equals(get(i)))

* (if such an element exists).  Returns true if this list

* contained the specified element (or equivalently, if this list

* changed as a result of the call).

*

* @param o element to be removed from this list, if present

* @return true if this list contained the specified element

*/







请到「今天看啥」查看全文