Nicholas Muir
Nicholas Muir

Reputation: 3114

For loop creating an array with one less value than expected

I am sure this is something really simple but I have not been able to work out what is going on for a while now.

I have a List I get from shared preference:

// Access the shared preferences to see if the user has saved any alarms yet
    SharedPreferences sharedPreferences = context.getSharedPreferences("AppData", Context.MODE_PRIVATE);
    String alarmsstring = sharedPreferences.getString("AlarmsStringSP", "None");

// Split the the main alarm string into array of strings values for alarm objects
    List<String> alarmObjectsArray = Arrays.asList(alarmsstring.split("\\s*;\\s*"));

I check the size of that list using:

System.out.println("Testing"+ alarmObjectsArray.size());

And I get:

I/System.out: Testing3

Which is what I expect so fine up to there.

I then create a new array list and put each element of the old list into the new one converted to an object.

Like this:

   // Iterate through the alarm objects, and place each item into the alarms array
    for (int i = 0; i < alarmObjectsArray.size()-1; i++){
        // For each of the alarm objects split them into their induvidual items so they can be
        // converted back to the correct type.
        List<String> alarmItems = Arrays.asList(alarmObjectsArray.get(i).split("\\s*,\\s*"));
        Alarm alarm = new Alarm(Integer.parseInt(alarmItems.get(0)),Integer.parseInt(alarmItems.get(1)),
                Boolean.parseBoolean(alarmItems.get(2)), Boolean.parseBoolean(alarmItems.get(3)),
                Boolean.parseBoolean(alarmItems.get(4)),Boolean.parseBoolean(alarmItems.get(5)),
                Boolean.parseBoolean(alarmItems.get(6)), Boolean.parseBoolean(alarmItems.get(7)),
                Boolean.parseBoolean(alarmItems.get(8)));
        alarms.add(alarm);
    }

The only thing is when it comes out of the for loop I check the new array size with:

System.out.println("Testing"+ alarms.size());

And I get:

I/System.out: Testing2

Somehow it has lost one when it was taken from the list into the array. I know there is a lot text in the for loop but I can't see any reason for having one less.

Upvotes: 0

Views: 1756

Answers (3)

Bathsheba
Bathsheba

Reputation: 234715

for (int i = 0; i < alarmObjectsArray.size(); ++i/*I'm an old-fashioned cat*/){ will index over every element in the array. (i will start at 0, and finish at and including a value one less than the size of the array).

Drop the -1 term.

For the avoidance of doubt, Java arrays are zero-based. Java ain't Fortran you know.

Finally, < size() is more idiomatic than the equivalent <= size() - 1. Futhermore size() - 1 can yield sheer devilry in C++ if size() is an unsigned type - as it often is - and happens to be zero!

Upvotes: 4

Pier Giorgio Misley
Pier Giorgio Misley

Reputation: 5351

Let's analyze this code:

for (int i = 0; i < alarmObjectsArray.size()-1; i++)
  • for means that the code inside the loop is done until the condition is true.

  • The first loop will run with i = 0, as you correctly set.

  • Every loop will add 1 to i since you wrote i++.

  • Your exit condition is i < size-1. Since size = 3, it means i < 3-1, equals to i < 2so the code will run for i = 0 and i = 1

This means the code will run only 2 times.

In for loop, if you want to avoid the foreach, use i < size or i <= size-1, otherwise you will lose an item.

Hope you understood the explaination.

Upvotes: 2

xenteros
xenteros

Reputation: 15842

As I see you do not certainly understand the for loop, so let's focus on it.

int[] array = new int[5];
System.out.println(array.size());
for (int i = 0; i < array.size(); i++) {
    System.out.println(i);
}

The above code will print:

>5
>0
>1
>2
>3
>4

The array has 5 cells. The're 0-indexed so the indexes start from 0. It results in last cell having the index of array.size() - 1. So if you want to loop through all indexes you have to loop from 0 to array.size()-1.

Upvotes: 1

Related Questions