I am working through lessons in Java, and have not been able to completely understand what is going on in the following lesson.
Purpose: The purpose of this lesson is to explain how a for-each loop works by creating an alternative that simulates how the for-each loop would work.
In the previous lesson, the explanation of the for-each loop was simple:
import java.util.ArrayList //Imports ArrayList CLASS
public class ForEachLoops
{
public static void main(String[] args)
{
ArrayList<Integer> numbers = new ArrayList<Integer>();
// ^ Creates ArrayList object & calls constructor
for(int i = 1; i < 11; ++i)
numbers.add(i); //Just adding numbers 1-10 to the ArrayList.
for(int n : numbers) //For-Each Loop
System.out.println(n); //Returns value from each ArrayList element
}
}
In the next lesson, the instructor was showing how to create an alternative/simulator of the for-each loop. It works as follows:
import java.util.ArrayList; //Importing ArrayList class from package
import java.util.Iterator; // Question 1 (See Below)
public class Chap16Part9
{
public static void main(String[] args)
{
ArrayList<Integer> numbers = new ArrayList<Integer>();
// ^ Creating object of ArrayList & calling constructor
for(int i = 1; i < 11; ++i)
numbers.add(i); //Just adding numbers 1-10 to ArrayList object
for(Iterator<Integer> n = numbers.iterator(); n.hasNext();) {
// ^ Question 2 (See Below)
int num = n.next(); //Points to the next element to assign value.
System.out.println(num); //Prints current value of "num."
}
}
}
Question 1: After reading the Java documentation, "Iterator" is listed as an interface. Is this still the same as importing a class? For example, in the Java documentation, "java.util.Scanner" is considered a class, and not an interface.
Question 2: Before asking the question, the loop does not need a "++i" type of control implemented because the hasNext() method of the Iterator checks to see if there is another element to check. If not, then it stop. It's a boolean value. The beginning of the loop, however, the loop-control variable (LCV) is "Iterator<Integer> n = numbers.iterator();" and I am not quite understand what is meant by this. In my eyes, I see an object of the Iterator class? being set equal to the ArrayList iterator() method. Could it be because given that "java.util.Interator;" is considered an interface (basically a contract that has declared methods that must be implemented if it is implemented by a class), the ArrayList class completes the set of statements of the declared iterator() methods in the ArrayList class and, therefore, needs to be called that way instead of by a constructor as traditional classes are called (the ArrayList, for example)? I am a bit confused by this, and I am hoping somebody can shed light on this. Thank you!
2 Answers 2
Java reference types include classes, interfaces and enums (as well as arrays, but they are a bit different). All of them are pieces of code that define behavior, and therefore need to be imported for your program to know which methods are available in them, etc.
So an interface such as Iterator has code that says which methods and constants are defined in it, which parameters the methods accept, what types they return, and so on. The compiler must know all that to be able to check the correctness of your program and generate the proper calls to those methods in the byte code that it creates.
The method iterator() in List returns an iterator over the items in that list. That is, an object from a class that implements Iterator. You don't know which class that would be and how it's implemented - that information is encapsulated in the particular list's code - but you do know that it implements Iterator and therefore has all the methods declared in Iterator and implements them according to the Iterator contract.
For this reason, you can assign a reference to any object that implements an interface X to a variable whose type is X, even though it's just an interface type. That variable points to an actual object from some class, but the program is only interested in the fact that it implements X.
Iterator<Integer> n = numbers.iterator();
Does exactly that. It says "declare n as a variable of the interface type Iterator<Integer>. Ask the numbers list for its iterator, and assign it to n. So your "loop variable" is actually the Iterator object. Because you know it is of type Iterator - implements the Iterator contract - you know you can use hasNext() and next() on it. And that's what you do in the loop condition check and in the following line.
Comments
An interface is similar to a class but instead of constructing a new class an interface is implemented using the keyword implements. The iterator interface is implemented in many Java standard classes.
Imagine you have a ball factory. It can pump out tennis balls and basketballs which are your classes. But when both tennis and basketballs are made they have similar properties such as isRound() and bounce() and so forth. An interface is like having those properties grouped together under a name. So both the tennisball and basketball implement the interface Ball.
So in List which implements iterable you can use a iterable method called iterator which is something that can go through the elements of a list. Arraylist also gets iterable through inheriting List.
<whatever>being treated as HTML tag which instead of being shown is interpreted always wrap code fragment using`.ArrayListis (implements)Listwhich is (extends)Collectionwhich is (extends)Iterable(notice it is notIterator, butIterablepurpose is to ensure that class can returnIteratorfrom by callingiterator()method).