简体   繁体   中英

Java loops issues after removing

So I'm trying to loop through some values of a array but at the same time in another method I'm reducing the elements in the array.

For example I have the names:

Susie Jim Jerry Fausty Jerry Jim Fausty Susie Jim Jerry Fausty Susie Jerry Jim Fausty Susie Fausty Jim Fausty Susie

Then I remove susie and fausty when then makes Jerry appear at element 2 times and Jim appear at element 0 3 times instead of once.

public String firstChoiceFrom (ArrayList<String> List)
{ 
      String name="";


       for(int i=0; i<List.size()-1; i++)
        {
            if(List.get(i).equals(ballot.get(i)))
            {
                 name = this.ballot.get(i);
            }
        }

       //String name = this.ballot.get(0);

        return name;

}
public int numberOfFirst(String name, ArrayList<String> List) {
    int m= 0;

    for (int i = 0; i < ballotList.size()-1; i++) {
        if (name.equals(ballotList.get(i).firstChoiceFrom(List))) 
        {
            m++;
        }
    }


    return m;
}

I'm able to remove the elements but seems like I'm unable to to get the elements after the remove

Use the List's Iterator which will allow you to traverse through the list as well as remove items in the same loop. This will also ensure inconsistencies don't occur. Use this method list.iterator()

It can be done with a for loop as well,

while (iterator.hasNext())
{
    String value = iterator.next();
    if (<some check condition>)
    {
        iterator.remove();
    }
}

This will work neater.

I would mention another iterator-based approach, in an attempt to combine the two answers already given. On one hand, using iterators will allow element removal; on the other hand, if we expect to be removing really many items (or all of them) then with ArrayList it's really better to traverse it in reverse order, to minimize the count of items "after" the one being removed (for each removal).

In this case, I suppose you could use list.listIterator(list.size()) instead of list.iterator(), then proceed to its previous() at each iteration. Will only work for lists, though.

My suggestion for removal if you are using Java 8 is ArrayList.removeIf . It's very simple to use and very safe:

myArrayList.removeIf(name -> name.contains("J"));

Most of the code you have posted can be simplified with Java 8 streams. For example:

public int numberOfFirsts(String name, ArrayList<String> list) {
    return list.stream()
        .filter(ballot -> name.equals(ballot.firstChoiceFrom(list)))
        .count();
}

You are confusing arrays with lists.

An array is a consecutive area of memory that contains values. A list is an ordered collection of a values. The difference is that an array has a fixed size while the size of a list adjusts to accommodate the addition or removal of elements.

We have an array with a length of 5.

["A","B","C","D",null]

Removing "A" from the array results in array that still has a length of 5

[null,"B","C","D",null]

We have a list with a size of 4 and a capacity of 5.

["A","B","C","D"]

Removing "A" from the array results in a list that has a size of 3. Every elements has been moved one spot to the left.

["B","C","D"]

So when removing elements from a list in a loop, you will skip over the item that has been moved to the left as you can see below.

    List<String> l = new ArrayList<String>(Arrays.asList(new String[]{"A","B","C","D"}));

    System.out.println(l);
    for(int i = 0; i < l.size() ; i++){
        System.out.println(i + " " +  l);
        String r = l.remove(i);
        System.out.println("Removed " +  r);
    }


    // Prints
    // [A, B, C, D]
    // 0 [A, B, C, D]
    // Removed A
    // 1 [B, C, D]
    // Removed C

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM