Your array has 8 elements, so array.length=8.
Therefore array.length-1 = 8-1 = 7.
You are running the loop from when i is 0, until i is less than 7. So it will run from i=0 to i=6.
To traverse the entire array, you need to run it from i=0 to i=7 instead.
So change
i< array.length -1
to
i < array.length
or
i <= array.length - 1
Answer from Kartik on Stack OverflowYour array has 8 elements, so array.length=8.
Therefore array.length-1 = 8-1 = 7.
You are running the loop from when i is 0, until i is less than 7. So it will run from i=0 to i=6.
To traverse the entire array, you need to run it from i=0 to i=7 instead.
So change
i< array.length -1
to
i < array.length
or
i <= array.length - 1
to make it super clear let us understand it the other way round. The length of your array here is 8. When talking about indexing of arrays,we know that index always starts from 0. The reason behind arr.length-1 is, we are looping all the elements from i=0 to i=6 as array lenght=8 and i<8-1 means i<7 so it would result in printing only from 0 to 6.. So its going to print elements only upto :[23,75,982,22,74,45,0]. Code should be changed from i<arr.length-1 to i<arr.length and you will print all values. Specially,arr.length-1 is used only when working with i+1 elements (Finding duplicates,etc.) because there, we don't want the index to go out of bounds.
For an array of length=3 when i=0, "next element exists only for 0 which is 1, and for 1 which is 2. There exists no next element for the 3rd element". Hope it gave you some clarity. Cheers.
Let me first highlight three different ways for similar purpose.
length -- arrays (int[], double[], String[]) -- to know the length of the arrays
length() -- String related Object (String, StringBuilder, etc) -- to know the length of the String
size() -- Collection Object (ArrayList, Set, etc) -- to know the size of the Collection
Now forget about length() consider just length and size().
length is not a method, so it completely makes sense that it will not work on objects. It only works on arrays.
size() its name describes it better and as it is a method, it will be used in the case of those objects who work with collection (collection frameworks) as I said up there.
Now come to length():
String is not a primitive array (so we can't use .length) and also not a Collection (so we cant use .size()) that's why we also need a different one which is length() (keep the differences and serve the purpose).
As answer to Why?
I find it useful, easy to remember and use and friendly.
A bit simplified you can think of it as arrays being a special case and not ordinary classes (a bit like primitives, but not). String and all the collections are classes, hence the methods to get size, length or similar things.
I guess the reason at the time of the design was performance. If they created it today they had probably come up with something like array-backed collection classes instead.
If anyone is interested, here is a small snippet of code to illustrate the difference between the two in generated code, first the source:
public class LengthTest {
public static void main(String[] args) {
int[] array = {12,1,4};
String string = "Hoo";
System.out.println(array.length);
System.out.println(string.length());
}
}
Cutting a way the not so important part of the byte code, running javap -c on the class results in the following for the two last lines:
20: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_1
24: arraylength
25: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
28: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
31: aload_2
32: invokevirtual #5; //Method java/lang/String.length:()I
35: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
In the first case (20-25) the code just asks the JVM for the size of the array (in JNI this would have been a call to GetArrayLength()) whereas in the String case (28-35) it needs to do a method call to get the length.
In the mid 1990s, without good JITs and stuff, it would have killed performance totally to only have the java.util.Vector (or something similar) and not a language construct which didn't really behave like a class but was fast. They could of course have masked the property as a method call and handled it in the compiler but I think it would have been even more confusing to have a method on something that isn't a real class.
You want to use oldArray.length usually in a for loop call, because as in your example,
for(int i = 0; i < oldArray.length; i++) {
//Executes from i = 0 to i = oldArray.length - 1 (inclusive)
}
Notice how i goes from 0 up until oldArray.length - 1, but stops exacty at oldArray.length (and doesn't execute). Since arrays start at position 0 instead of 1, old.Array.length is a perfect fit for the number that i should stop at. If arrays started at position 1 instead, for loops would look something like this:
for(int i = 1; i <= oldArray.length; i++) {
//Executes from i = 1 to i = oldArray.length (inclusive)
}
oldArray.length - 1 is usually to access the last element:
int[] oldArray = {1,2,3,4,5};
int lastElement = oldArray.length - 1; // 4
oldArray[lastElement] // returns last element, 5
Although this is usually when you would use length - 1 vs length, there are many other cases where you would also want one over the other, and thus there is no real specific answer. But don't worry, keep coding, you'll get this hang of this soon ;)
for(int i = 0; i < oldArray.length; i++)
is equivalent to
for(int i = 0; i <= oldArray.length - 1; i++)