简体   繁体   中英

Why is this loop only running once

The following for loop ( for (int curr = 0; curr<working.size(); curr++){ ) loop should run n times, where n is the size of the ArrayList called working. However, even after verifying that the ArrayList has multiple elements in it, the loop only runs once. Why is this?

 String sql = "SELECT time FROM `tutors`.`appointments`"
            + "WHERE tutorID = ? AND date = ?";

          try{
    for (int curr = 0; curr<working.size(); curr++){       
        System.out.println("working size: " + working.size());
        System.out.println("running for the time: " + curr);

        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, working.get(curr).getTutorID());
        ps.setDate(2, toReturn);

        ResultSet rs = ps.executeQuery();

        while(rs.next()){
            Time t = rs.getTime("time");
            System.out.println("RS HAS : " + t);
            long beforeLong = t.getTime()-900000;
            long afterLong = t.getTime()+900000;

            Time beforeTime = new Time(beforeLong);
            Time afterTime = new Time(afterLong);

            if (!time.before(beforeTime) && !time.after(afterTime)){
                System.out.println("removed" + working.get(curr).getName());
                working.remove(curr);
            }
        } 
    }
        } catch(SQLException e) {e.printStackTrace();}

PS - I have the same problem whether I put the try/catch inside the for loop or outside of it.

You remove elements while iterating.

Suppose your list has size 2 : At first iteration you remove one element, and then the loop stops because curr is 1 which is the size of the list.

Use an iterator to iterate over a list if you remove elements :

Iterator it = working.iterator();
while (it.hasNext()) {
    ...
    it.remove();
}

The ArrayList iterator is safe for this operation.

The loop is conditioned on working.size(), do any of the methods called inside the loop change this? I see you have working.remove() in there, which might be changing the loop termination condition.

Try printing the value of working.size() at the end of the loop as well as at the beginning.

There is a chance that you might end up removing all the elements in the list with the first iteration of the for loop. Lets see how (consider first iteration, curr = 0 ).

There might be multiple records in rs after this statement has been executed:

ResultSet rs = ps.executeQuery();

As a result the following while may end up running multiple times:

while(rs.next())

Now whenever this condition evaluates to true for any of those records:

!time.before(beforeTime) && !time.after(afterTime)

the element at index 0 (as curr = 0 ) is removed from working :

working.remove(curr);

But with this removal other elements are shifted towards left in the list, which means another element comes at index 0 , which essentially becomes a candidate for removal in another iteration of the while loop.

ArrayList.remove :

Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).

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