Just need a quick clarification:
While using the iterator class, can I create a iterator object like below:
Option1: <Class-name>Iterator [Iterator-object] = <object-name>.iterator();
or should i be sticking to
Option2: Iterator<Class-name> [Iterator-object] = <object-name>.iterator();
Can you briefly explain why the suggested one is correct?
Use Option 2. As syntactically correct Java, it will enable your program to be compiled.
Iterator<T> iter = someObject.iterator() is correct.
But if someObject is Iterable (like, for example, a java.util.List) and all you need to do is actually iterator over it, use a 'for-each' loop:
for(T thing : someObject) { /* do stuff with 'thing' */ }
Did you look at the documentation?
Iterator<E> iterator()
...
all depends on what you exaclty wanted to itrate either a ArrayList/List or any other collection of string /object.
eg you wanted to itrate on a ArrayList then you take
ArrayList al =(you data );
Itrator itr=al.itrator ();
also you can view how to use itrators for help http://www.javapractices.com/topic/TopicAction.do?Id=125
Related
Suppose I have a list of some class A defined as:
Object list = new ArrayList<A>();
I want to iterate over this. Is it possible? If yes then how? Even if I find the type of list using reflections then also I won't get to class A.
Also, note that I don't know what class A is. I just have list.
If you instantiate an ArrayList the way that you've shown (you want it to be treated as Object - this class doesn't allow iterating, classes implementing Iterable interface provide this function), and then you need to iterate over its elements, you can cast this list from Object to Iterable, that way iteration becomes available for list:
for(A a : (Iterable<A>) list) {
// do stuff
}
or when you need an Iterator iterating over elements of the list:
Object list = new ArrayList<A> ();
Iterator<A> it = ((Iterable<A>)list).iterator();
You might want to have a look at Java API Documentation of to read more about Iterable interface here.
Edit: This answer was edited thanks to helpful suggestions of Federico Peralta Schaffner and luk2302.
I found a way to do so. I did something like this:
List<?> list1 = (List<?>) list;
now I can iterate as,
for(Object o : list1) {
// code
}
Please be aware this is a false issue. I asked it because when I tried to use Iterator, my IntelliJ keeps alarming on "Iterator" saying Iterator could not have type parameters, which is not true.
Somehow, my IntelliJ seems to showing the javadoc of java 1.4. I am still trying to fix it. Thanks.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I worked on a java program where an api returns a List.
My way of handling this is:
ArrayList<SomeObject> arrayList = new ArrayList<>(apiThatReturnsAList);
for (SomeObject someObject : arrayList) {
...
}
My code reviewer suggests this might be a less efficient way to deal with it because it copies the data. He recommended I use Iterator. But I find the code would be like this:
Iterator iterator = apiThatReturnsAList.iterator();
while (iterator.hasNext()) {
SomeObject someObject = (SomeObject)iterator.next();
}
There is ugly casting here which we don't want to see because it is not safe.
So, is there an efficient way to deal with this api and not copying the data?
Thanks!
To avoid a copying, you can use foreach for apiThatReturnsAList
for (SomeObject someObject : apiThatReturnsAList) {
...
}
In fact, foreach does the same work with iterator under the hood JLS 14.14.2. The enhanced for statement
Just parameterize your iterator with the expected class:
Iterator<SomeObject> iterator = apiThatReturnsAList.iterator();
and you will get a SomeObject instance when you call next() :
Iterator<SomeObject> iterator = apiThatReturnsAList.iterator();
while (iterator.hasNext()) {
SomeObject someObject = iterator.next();
}
Use a for-each to print the contents of the elements in the apiThatReturnsList:
for (SomeObject element : apiThatReturnsList) {
System.out.println(element);
}
There's no need to copy the list into another list.
I have class which has an Iterator method ( public Iterator iterator(boolean fromFront) ) and my Iterator method returns a "new DoublyLinkedListIterator()". DoublyLinkedListIterator implements ListIterator which contains the set method. The problem is in my main where my iterator doesn't have access to the set method, Iterator iterator = deque.iterator(true); Nor do I have access to the hasPrevious or previous methods.
If you want to have access to the methods in DoublyLinkedListIterator, you have to return it instead of an Iterator. (Or make a cast before using it).
How to make a cast, in case you need it.
The standard way to expose a ListIterator is to have a public <T> ListIterator<T> listIterator() method on your class, as in the standard List class, so you can use it as:
ListIterator literator = deque.listIterator();
Note that the builtin Deque<T> class does not support ListIterators. The variable name is taken from your sample code, it has a custom type.
If you want to use iterator but want to navigate forward/backward and change the links order, ... to be short every write operation that modify the structure of the list, you're doing it wrong.
Go for the while/do-while loop if you have such needs.
Iterator<String> iterator=...
//right way
for (Iterator<String> i = iterator; i.hasNext(); ){
System.out.println(i.next());
}
//why can't?
for(String i:iterator){
}
Reference:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
http://docs.oracle.com/javase/6/docs/api/java/util/Iterator.html
You can do more compactly:
for(String i:list){
}
The syntax is only for Iterables (and arrays), not for their Iterators directly (and also not for Enumerations).
Why not? I don't know... Maybe too much complexity/effort (in the compiler implementation) for a "rare" case. Or edge-cases that would cause trouble (such as an Iterable that is also an Iterator, I think some people make such beasts).
Maybe try libraries like Google Guava to get some more convenient ways to work with Iterators, Collections, and friends.
The compiler checks the syntax for the for enhanced and requires that the expression after the colon returns an object that implements the Iterable interface. Iterator doesn't implement it.
You can only use the for loop syntax with objects that implement the Iterable interface.
Iterators are not iterable.
for(String i:list){
//
}
I'm completely new to iterators. I have an ArrayList named "Test" with String objects. How would I go about using an iterator class? I've tried everything I can think of, it's just not making sense. Thanks for the help.
Say I have an Iterator named "iter". I need to step through my ArrayList in search of a certain String. When that String is found, I need to add it to a different ArrayList named "test2".
while(iter.hasNext()) {
if(iter.next() == sampleString) {
test2.add(sampleString);
}
}
Only problem with this, is that when I call next() it moves the pointer to the next String, ignoring the first String in the ArrayList. How would I implement this??
You don't need one. The ArrayList is already Iterable! :-D
ArrayList<String> test = new ArrayList<String>();
test.add("Hello");
test.add("world");
for(String str : test) System.out.println(str);
Iterators are generally used like this:
while (iter.hasNext()) {
String nextString = iter.next();
// Do something with the string...
}
Some (myself included) will prefer the enhanced for loop:
for (String nextString : listOfStrings) {
// Do something with the string
}
The for loop avoids the need for getting an explicit Iterator reference and includes the nextString variable declaration, keeping it concise and properly scoped.
The issue is that your not quite 100% on how Iterator.next() works
This is copied directly from the Java API
E next() -- Returns the next element in the iteration.
What this means is that .next() will return an object then move to the next item in the list.
You need to store the returned object when calling next()
while(iter.hasNext())
{
String temp = iter.next();
//this is a more old school method but more true to form.
//== doesn't necessarily do equality checks on all objects the way
//you would think
if(temp.equals(sampleString))
{
test2.add(temp);
}
}
An iterator is simply something that understands how to traverse a given data structure.
What is it that you aren't understanding?
For a List an iterator would keep track of its current position in the list and understand how to get the next element in the list. For something like a list, it's relatively simple, but you could also define an iterator for some other arbitrary data structure that isn't as simple as a list. You could also define one that does something differently like traverse the list backwards. If you have specific questions about iterators, update your question and we'll take a stab at it :-)
Iterator is a means of traversing a collection of items. Adhering to that statement, the java.util.Collection extends Iterable (public interface Collection<E> extends Iterable<E>). i.e all collection classes are Iterable in someway. iterator() is the method to get a handle to that Iterator. Once you have the handle you can traverse through the items.
I highlighted someway because not all Iterator's allow bi-directional traversal. ListIterator allows this.
I'd rewrite your code as below
for(String s : myCollection)
{
if(s.equals(sampleString))
{
test.add(s);
}
}