Traversing arraylist makes mistakes
Scenes:
Delete the recorded record in ArrayList, the program written in the first time is as follows:
FOREACH (String Astr in Alist)
{
IF (askBOX1.TEXT))
{
Alist.Remove (Astr);
}
}
There seems to be no mistakes, compiling, but if you really encounter qualified data, you will throw errors:
How is a simple solution? At this time, it is best to use the clone method, use the following code:
ArrayList Blist = (arraylist) alist.clone ();
FOREACH (String astr in blist)
{
IF (askBOX1.TEXT))
{
Alist.Remove (Astr);
}
}
It seems that there is such a problem.
Posted on 2004-09-08 13:53 Wind Flood ~~ Read (1047) Comments (25) Edit Collection
comment
# Re: Traversing arraylist makes mistakes
Use for to avoid such problems, and the effective performance efficiency is high in Foreach.
2004-09-08 14:10 | Nothing
# Re: Traversing arraylist makes mistakes
Ah, you ..... You actually ... actually dare to use Foreach to reomove, this is the notorious collection problem .....
2004-09-08 14:24 | Han Feng Tianhua
# Re: Traversing arraylist makes mistakes
I usually use
Foreach (Object Item in Al.toArray ())
.
Or IN New ArrayList (SomeCollection).
2004-09-08 14:55 | lostinet
# Re: Traversing arraylist makes mistakes
It seems to have a simple copy of a shallow copy.
It is best to use which one, don't use Clone
2004-09-08 15:11 | Hyifeng
# Re: Traversing arraylist makes mistakes
Use the for statement to reverse traversal
2004-09-08 16:07 | Feilng
# Re: Traversing arraylist makes mistakes
I also commit such a mistake, huh, huh
2004-09-08 16:10 | CURE
# Re: Traversing arraylist makes mistakes
Do not know anything:
The method of For can also, the code is as follows?
For (int i = 0; i IF (Alist [i] .Equals (TextBox1.text)) Alist.Removeat (i); To lostinet: Your method is also good. To Hyifeng: For ArrayList, Clone is already a shallow copy. Are you talking about MEMBERWISECLONE? It seems that there are three ways to handle, in Foreach, use Clone, for loops, toarray, don't know what it is better? How can I get the comparison data? 2004-09-08 16:12 | Front flves ~~ # Re: Traversing arraylist makes mistakes To Feilng: Reverse traversal? Is there any benefit? How can I achieve it? 2004-09-08 16:18 | Fall forward ~~ # Re: Traversing arraylist makes mistakes I have passed, and For should be the safest, and it is easy to understand. CLONE and TOARRAY have increased at least the amount of processing 2004-09-08 16:23 | Dali # RE: Traversing arraylist makes mistakes TO windfall ~~: For FOR code, you should add a conditional branch. If the REMOVEAT method is called, INDEX cannot be increased. That is to say, the cyclic incremental statement should not be written inside the parentheses of for. 2004-09-08 17:56 | FantasySoft # RE: Traversing arraylist is easy to accept you, actually. . . . This kind of low-level mistake is committed! ! ! ! One is still not tight, it is a group! ! ! Halo ~ Deleted code as follows: for (int i = alist.count; --i> = 0;) IF (alist [i] .Equals (textbox1.text)) Alist.Removeat (i); 2004-09-08 18:54 | Old wings # Re: Traversing arraylist makes mistakes Oh ~ 2004-09-08 19:20 | HBIFTS # Re: Traversing arraylist makes mistakes TO old wings: Haha ~~ If you can't say this, there will be no mistakes there? Don't have bugs. Thank you for your code, I tried it, no problem, can be said to be a method of for. To fantasysoft: My code is also passed, can achieve the effect, please indicate my code error, thank you! 2004-09-08 19:58 | Front floc ~~ # Re: Traversing arraylist makes mistakes TO windfall ~~: The code itself is not wrong, just logically there is a problem. Because the Removeat method changes the return value of the count method, it is caused to be traversed in each element. This is also the reasons for the reverse traversal of Feilng and the old wings. Please see the following code: Using system.collections; Using system; Class test { Public static void main () { Arraylist test = new arraylist (); For (int i = 0; i <3; i ) Test.add ("test"); Test.Add ("Testagain"); Test.Add ("Testagain"); For (int i = 0; i { IF (TEST [I]. Equals ("Test"))) Test.Removeat (i); } For (int i = 0; i Console.writeline (TEST [I]); } } Test this "Test" inside ArrayList should be removed by remove? In fact, if you write, there will be one left. 2004-09-09 02:22 | FantasySoft # Re: Traversing arraylist makes mistakes To fantasysoft: Thank you very much! The original code did not find this problem because each is different. Come carefully, it is indeed, if you say: Count change, make index = 0 to be missed. It seems that the way for speaking is only inversely traversed. There is an air with Ildasm to see the code generated by the three different methods. Compare the corresponding function, the same, the maximum number of stacks is found, the length of the code is different, the shortest of Forlay (), the most. It is ok to add a statement to the method, but it looks bloated than reverse: For (int i = 0; i IF (Alist [i] .Equals (TextBox1.text)) { Alist.Removeat (i); I-; } 2004-09-09 09:18 | Front floc ~~ # Re: Traversing arraylist makes mistakes TO windfall ~~: can write this way For (int i = 0; i IF (Alist [i] .Equals (TextBox1.text)) { Alist.Removeat (i); } Else i ; Does this writing are clearer? The increasing statement of For is not necessarily written to the parentheses of for. 2004-09-09 10:24 | FantasySoft # Re: Traversing arraylist makes mistakes Yes, it is also a way! ^ _ ^ 2004-09-09 10:36 | Front floc ~~ # Re: Traversing arraylist makes mistakes I would like to say that I saw that the landlord is "carefully, it is really like what you said: COUNT has changed, making index = 0 to be missed." This sentence, I don't really understand why I will generate the building Top problem Improving is not the original List 0 Item, but No. 1 Item why? Because when you Remove iTem, all Items' index value in the [i 1, count) domain is reduced (Array is continuous, you must satisfy as long as there is k ∈ [0, count) Array [k] There must be), then when you use I 1 for indexing in the loop, it is an index of I 2 in the original list, which is known that when the No. 0 is deleted, the original 1 Changed to the new No. 0, the original No. 2 changed to the new No. 1. . . The No. 1 of the next round is the previous No. 2, and the original No. 1 will never be visited. Understand this natural iterative method, you need to pay attention to the termination conditions of indexing and possible changes in the positive order, simple sequence is simple. 2004-09-09 14:44 | # Re: Traversing arraylist makes mistakes TO problem male: OH ~~ Sorry, it is estimated that I have a problem with my expression. INDEX = 0 is relentable after COUNT, its original index is indeed = 1, just as you said. Thank you for your finger! 2004-09-09 15:16 | Fall forward ~~ # Re: Traversing arraylist makes mistakes Re: Traversing arraylist makes mistakes Use the for statement to reverse traversal 2004-09-08 16:07 | Feilng I agree with it, I think this is the best way. P.S. This kind of thing, people who have no error will be mistaken for the first time, haha 2004-09-09 16:56 | Myrat # Re: Traversing arraylist makes mistakes Look at this code, what results will there be? Int [] myarray = {1, 2, 3}; Foreach (int Num in myarray) { Num ; } 2004-09-09 17:21 | Juqiang # Re: Traversing arraylist makes mistakes To Juqing: Interesting It should not be no ---------------------------------------------- ---------------------------------- Description of MSDN: The Foreach statement repeats an embedded statement group for each element in an array or an object collection. The Foreach statement is used to loop access sets to get the required information, but not to change the collection content to avoid unpredictable side effects. -------------------------------------------------- ------------------------------ Num is equivalent to Num = Num 1, modify the content. Compile error: ... (201): Unable to be assigned to "NUM" because it is read-only 2004-09-09 17:33 | Fengfa-sales ~~ # Traversing arraylist makes mistakes [TRACKBACK] Ping Back from: blog.9cbs.net WINDSAILS quoted this article, address: Http://blog.9cbs.net/windsails/archive/2004/09/10/100331.aspx 2004-09-10 13:21 | WINDSAILS # Re: Traversing arraylist makes mistakes Why do you want to reverse? INT i = 0; While (i { IF (Alist [i] .Equals (TextBox1.text)) { Alist.removeat (i) CONTINUE; } i ; } 2004-10-20 21:29 | Warrior sailor # Re: Traversing arraylist makes mistakes Simple in reverse and high efficiency, alist.count is only used once in initialization, and other situations should be used every time. Although Alist.count is also a variable, but from the perspective of the machine code, indirect address references still have much more time to quote more than registers. 2004-12-09 12:45 | 无 名