1

I am currently in the process of learning the Java programming language, and I need help understand the size method of the ArrayList class. Before asking the question, let me explain the program.

This program finds the average of class grades.

My question would be about the size method of the ArrayList class. In the For-Loop, the relational expression, "i < grades.size()", will run "i" until it is less than the size of the array. I was instructed that the size of the array is always one more than the number of elements in the array, so in my case, given that I have 3 elements (grades) in my array, I actually have an array size of 4 (similar to how a string works). Notice that after I am out of the For-Loop, I am able to appropriately calculate my average with the size method. I am confused because if the size of the array would be one more than the number of elements, then would it not just divide by 4 rather than 3? Why do the rules function differently in a For-Loop? Thank you for anybody willing to shed light on this.

    import java.util.ArrayList; 


public class Chap11Part1 

    public static void main(String[] args)
    {
        double average;
        int total = 0;
        ArrayList<Integer> grades = new ArrayList<Integer>();
        grades.add(78);
        grades.add(84);
        grades.add(90);
        for(int i = 0; i < grades.size(); ++i) 
            total += grades.get(i); 
        average = total / grades.size();
        System.out.println("The average is " + average);
Peter Tillemans
  • 34,983
  • 11
  • 83
  • 114
Jeff Sours
  • 101
  • 1
  • 2
  • 11
  • 1
    size is exactly the same as number of elements. Note that they counted starting from 0, not 1. – Tagir Valeev Jun 01 '15 at 16:39
  • 1
    No braces (your for loop) = possible trouble in the future –  Jun 01 '15 at 16:40
  • 2
    @RC. it didnt need braces – Lrrr Jun 01 '15 at 16:41
  • 6
    You misunderstand the "size of the array is always one more than the number of elements." It's actually **one more than the largest index**. If you have 3 elements, you have a maximum index of `2` (`0`, `1` and `2`) which is 3 separate elements. If you called `.size()` on a such a list you would get `3` back. – Brandon Buck Jun 01 '15 at 16:41
  • To explain RC answer. You for loop will only using the next statement if you do not set braces to capsulate the scope of the loop. – JacksOnF1re Jun 01 '15 at 16:42
  • @Lrrr What RC probably meant is that it _could_ become a problem later on. Obviously it's not a problem now but it's cross-language accepted good practice to always include braces as it forgoes simple errors in the long run and clearly denotes blocks. – Brandon Buck Jun 01 '15 at 16:42
  • 2
    RC, I appreciate the response, however, I do not believe that would have affected my code. Remember, when coding in Java, single-statement loops can be written without parentheses. – Jeff Sours Jun 01 '15 at 16:43
  • 2
    At the cost of igniting a small flame, it *is* considered good practice (and mandated in several style guides) to always include braces in non-one-liner `for`, `while` and `if/then/else` blocks... *EDIT - one-liner interpreted as in "not ending in the same line that contains the opening `for`", and not as in "single-statement"* – tucuxi Jun 01 '15 at 16:44
  • 1
    clarified my comment, and @JeffSours coming from someone asking about `size()`, I think you should stick to "always use braces" (NB: it's an advice) –  Jun 01 '15 at 16:45
  • @tucuxi Did you make an error in a comment? Excluding braces in non-one-liner's is a logic error. So style guides aside it's a language level requirement. – Brandon Buck Jun 01 '15 at 16:45
  • @JeffSours is your doubt clear now? index start from 0 so the first element have index 0 and so on so if you have 4 elements you have 0-3 indexes – singhakash Jun 01 '15 at 16:45
  • @BrandonBuck clarified earlier comment – tucuxi Jun 01 '15 at 16:49
  • Also, don't use `++i` unless it will make a difference. Because it is more common to see `i++`, you will make other programmers look for why you used the previous then they will be left confused when they can't find why it would make a difference. To learn more about it check out this post: http://stackoverflow.com/questions/484462/difference-between-i-and-i-in-a-loop – Matt C Jun 01 '15 at 16:50
  • @MatthewC That doesn't really sound like a good reason. You should be able to see immediately what `++i` does and `i++` does immediately if you have any understanding of languages that support it. And, without talking about potential (and minor) speed improvements, I'd recommend always using pre-fix (`++i`) when you don't want the pre-increment value, or when it's a lone expression and only using post-fix (`i++`) when you need the current value before incrementing. – Brandon Buck Jun 01 '15 at 17:02
  • @tucuxi I see what you're saying now. Makes more sense. – Brandon Buck Jun 01 '15 at 17:02

3 Answers3

3

size of the array is same as number of elements. Only thing to remember is index starts with 0; So last index will be size-1:

import java.util.ArrayList;

public class Chap11Part1 {

    public static void main(String[] args) {
        double average;
        int total = 0;
        ArrayList<Integer> grades = new ArrayList<Integer>();
        grades.add(78);
        grades.add(84);
        grades.add(90);
        for (int i = 0; i < grades.size(); ++i)
            total += grades.get(i);
        average = total / grades.size();
        System.out.println("The average is " + average);
    }
}
Rajesh
  • 2,135
  • 1
  • 12
  • 14
  • I would add a println before the for loop to show clearly the size of the array. That would help clarifying IMO. – Peter Tillemans Jun 01 '15 at 16:48
  • I think I understand it now. I am starting "i" at zero in the For-Loop. As state by Rajesh, the size of the grades will be returned by the same number of elements. The first element starts at zero, and I want the loop to stop before 3 because I do not have an element in the third compartment, so I could not get anything from that compartment to add to my total. At that point, my loop should stop. It is acceptable to use in my average calculation because it returns the number of elements. Thank you to everybody for helping me, and understanding programming styles! – Jeff Sours Jun 01 '15 at 17:07
0

As has been pointed out, you have a confusion that starts here:

I was instructed that the size of the array is always one more than the number of elements in the array, so in my case, given that I have 3 elements (grades) in my array, I actually have an array size of 4 (similar to how a string works).

Whether this misunderstanding was on part of the instructor explaining things or you misinterpreting the meaning is irrelevant. This understanding is the source of your confusion and ultimately the problem.

You are correct. And ArrayList's size function will return 1 more than something, similar to how Strings work as well. That something is the maximum index. Arrays (and ultimately ArrayLists, which is just a Data Structure implemented on top of an underlying array) have an index value that starts at 0 (not 1 like you typically would when counting). That means, if you had three numbers, you would end up with something like this:

numbers[0] = 10
numbers[1] = 108
numbers[2] = 309

(Ignore the psuedo-code like syntax, pay attention to the values in brackets here)

If I were to get the size (or length with certain types) I would get 3. You can clearly see there are only 3 numbers shown. The "one more than" aspect is one more than the maximum index. The maximum index here is 2, given that we start counting (index-wise) at 0.

This issue is one of the more common I've seen from new developers and it's often referred to as an "off-by-one error" or OBO Error as you want the first element of a list you may try list.get(1) when that's is actually the second element of the list, .get(0) would be the first.

So now...

You have 3 elements in your ArrayList, a call to .size would give (as you should expect) the number 3 in return. Your loop comparisons go like this:

Iteration 1: i = 0; 0 < 3 == true; execute body
Iteration 2: i = 1; 1 < 3 == true; execute body
Iteration 3: i = 2; 2 < 3 == true; execute body
Iteration 4: i = 3; 3 < 3 == false; jump over body

As you can see, your condition is checked "one more than the number of elements" times (in this case, 4) but only 3 times, or the actual number of elements, is the loop body executed or run. If you had accidentally used <= instead, you'd get an OBO Error by accessing "one more than the list contains." Thats why having a grasp on this whole "start at 0" counting system is going to be key, as well as understanding that sizes or locations tend to be one-greater than index values.

If any part of this is more confusing than it should be, let me know and I'll try to fix it up.

Brandon Buck
  • 7,177
  • 2
  • 30
  • 51
0

The elements in your array (78, 84, 90) are counted to give the size/length of the array, which is 3 (one more than the largest subscript) What you should know is that the index (position of each element) starts from 0. So in your list, 78 is at index 0, 84 at 1 and 90 at 2.

I think you should read more on the various methods of Arrays and Lists and also the difference between ++i and i++

Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132