0

I wanted to iterate over a cursor over a table with 2 rows of data. My first try was:

c.moveToFirst();
while(!c.isAfterLast()){
//this code runs once
c.moveToNext();
}

However after debugging I noticed that I am missing the last row of my data. And that was because the while loop ends when the mPos variable becomes equal to mCount in the counter. After replacing the above code with the one below the problem was solved:

c.moveToFirst();
do{
//this code runs twice
}while(c.moveToNext())

Essentially in the first method, the while loop runs 1 time less than the second one. Isn't isAfterLast supposed to return true only after the cursor passes the last row?

SoroushA
  • 2,043
  • 1
  • 13
  • 29
  • 1
    Are you sure that in the first code block, you had `c.moveToNext()` as the last line of code inside the while loop? Both of those really should do the same thing. – Daniel Nugent May 02 '16 at 21:06
  • What happens if you run the first code block on a cursor that has only one row of data? Does it cause the body of the loop not to execute at all? Does that mean c.isAfterLast() returns true immediately after the call to c.moveToFirst()? – jason44107 May 02 '16 at 21:10
  • And for that matter, what happens if you run the first block on an _empty_ cursor? Does it throw an exception? – jason44107 May 03 '16 at 01:57
  • @DanielNugent yes I'm sure that it is at the end – SoroushA May 03 '16 at 03:21
  • @jason44107 very good point. I'll test tomorrow morning and update the question with details – SoroushA May 03 '16 at 03:22
  • @jason44107 with zero entries c.moveToFirst returns false and c.isAfterLast is true as it's supposed to be. I'm having a hard time recreating the experiment with more than one entry. Today the mCount is 2 when I have to entries. Yesterday it was 1. Could it have been a database inconsistency? – SoroushA May 03 '16 at 14:09
  • @SoroushA That might be easier to answer if the lines of code referring to mCount and mPos had not been removed from the code blocks you posted. – jason44107 May 03 '16 at 14:40
  • @jason44107 mCount and mPos are variables of the android.database.Cursor class not mine. – SoroushA May 03 '16 at 15:06
  • @SoroushA Okay, got it. – jason44107 May 03 '16 at 15:27

1 Answers1

2

Note that moveToNext() returns a boolean signifying that there is a next (true), but ALSO, if true - it moves the cursor. So that in this case when you return to evaluate while(!c.isAfterLast()) after c.moveToNext(); you are already at the last item (and so the cursor is pointing to the position after the last row.

If your goal is to iterate through the cursor, then you can just do this:

while (c.moveToNext()) {
  //do whatever with your data - like 
  //String value = c.getString(c.getColumnIndex("SOME_COLUMN_NAME"));
}

You can look at the related discussion here.

Community
  • 1
  • 1
ishmaelMakitla
  • 3,784
  • 3
  • 26
  • 32
  • The two code blocks in the question really should do the same thing. See here: http://stackoverflow.com/questions/10723770/whats-the-best-way-to-iterate-an-android-cursor – Daniel Nugent May 02 '16 at 20:57