A common sense of programming: Do not delete the element itself (at least my own principle) during the loop. Otherwise, unexpected problems will occur.
And recently, see a former classmate wrote a piece of code is in the loop process to delete elements, I am very puzzled ah. And then decided to get rid of him. And then it triggered another massacre.
The original code is this:
PublicList<a>Getuserdebitcard (A cond) {List<A> list=Userservice.getcard (cond); List<A> result=NULL; if(list!=NULL&& list.size () >0) {collections.sort (list,NewComparator<a>(){ Public intCompare (A B1, a b2) {//Sort by Time if(Integer.valueof (B1.getaddtime ()) >integer.valueof (B2.getaddtime ())) { return-1; } return1; } }); A Bean=Geta (cond); Result=NewArraylist<a>(); if(bean!=NULL){ for(inti = 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); } returnresult; }
Look at the above code, I was very depressed, and then changed to the following:
PublicList<a>Getuserdebitcard (A cond) {List<A> list=Userservice.getcard (cond); List<A> result=NULL; if(list!=NULL&& list.size () >0) {collections.sort (list,NewComparator<a>(){ Public intCompare (A B1, a b2) {//Sort by Time if(Integer.valueof (B1.getaddtime ()) >integer.valueof (B2.getaddtime ())) { return-1; } return1; } }); A Bean=Geta (cond); Result=NewArraylist<>(); if(Bean! =NULL){ //Put the last card in the first placeInteger Lastaindex = 0; Integer listsize=list.size (); if(Listsize > 0) { for(inti = 0; i < listsize; i++) { if(List.get (i). Getcardnum (). Equals (Bean.getcardnum ())) {List.get (i). SETAs (1); Result.add (List.get (i)); //Add the first element and record the indexLastaindex =i;//List.remove (i); //deleting elements during a cycle is dangerous}Else{list.get (i). SETAs (0); }} list.remove (Lastaindex); }} result.addall (list); //Delete elements in the loop, thought everything is all right, the result is tragic, here actually added two elements come in } returnresult; }
This happened, originally only one element of result, now become two, this is why? Mother Egg, I have already removed the AH.
Also thought about Baidu a bit, but the wood has done ah. Then, take out the housekeeping trick, breakpoint debugging, into the List.remove (Integer) method. Its source code is as follows:
/*** 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 * <tt>i</tt> such that * <tt> (O==NULL&A mp;nbsp;? get (i) ==null : o.equals (get (i))) </tt> * (if such an element exists). Returns <tt>true</tt> If this list * contained the specified element (or equivalently, if this list * Changed as a result of the call). * * @paramo element to is removed from the this list, if present *@return<tt>true</tt> If this list contained the specified element*/ Public BooleanRemove (Object o) {if(O = =NULL) { for(intindex = 0; index < size; index++) if(Elementdata[index] = =NULL) {fastremove (index); return true; } } Else { for(intindex = 0; index < size; index++) if(O.equals (Elementdata[index])) {fastremove (index); return true; } } return false; }
Originally, because I use integer as a condition to delete elements, here the integer as an element to compare, and not usually we think of automatic unboxing into an int. The idea of entering this method is to find the element that is equal to the element content and then delete it. And I give an index, nature is not equal, no deletion is natural, because you will see the duplicate elements come out.
Let's take a look at the source code of the deleted element according to the index, compare:
/*** Removes the element at the specified position of this list. * Shifts Any subsequent elements to the left (subtracts one from their * indices). * * @paramIndex the index of the element to be removed *@returnThe element that is removed from the list *@throwsindexoutofboundsexception {@inheritDoc} */ PublicE Remove (intindex) {Rangecheck (index); Modcount++; E OldValue=Elementdata (index); intnummoved = size-index-1; if(nummoved > 0) system.arraycopy (elementdata, index+1, Elementdata, Index, nummoved); elementdata[--size] =NULL;//clear to let GC do it work returnOldValue; }
From here we can see that the principle of deleting the ArrayList element according to the index is to exclude the original array from the index to be deleted, then copy it to the new array, and then set the last element to NULL, leaving the GC to be recycled. and returns the deleted element.
In this way, it is clear what is the matter of deleting the ArrayList element. The fix is simple, replacing the integer with an int:
// Integer lastaindex = 0; // Replace with int int lastaindex = 0;
And, of course, in the end, I switched to another, more secure solution, to receive the final result with another container.
PublicList<a>Getuserdebitcard (A cond) {List<A> list=Userservice.getcard (cond); List<A> result=NULL; if(list!=NULL&& list.size () >0) {collections.sort (list,NewComparator<a>(){ Public intCompare (A B1, a b2) {//Sort by Time if(Integer.valueof (B1.getaddtime ()) >integer.valueof (B2.getaddtime ())) { return-1; } return1; } }); A Bean=Geta (cond); Result=NewArraylist<>(); if(Bean! =NULL){ //Put the last card in the first place for(A card1:list) {if(Card1.getcardnum (). Equals (Bean.getcardnum ())) {Card1.setas (1); Result.add (0, Card1);//Insert first position directly//List.remove (i); //deleting elements during a cycle is dangerous}Else{Card1.setas (0); Result.add (CARD1); } } } } returnresult; }
Although the automatic unpacking is very convenient, but also very practical, but sometimes accidentally will put themselves to bury in the pit, beware. Especially for online issues.
After all, a little bit of code in the problem, one to the line will be infinitely magnified, not lightly ah!
Java ArrayList Pit Record