Enforcing order in Java Iterator - java

I am providing a library for a different team. One of the methods I provide receives as argument an Iterator. I would like to somehow require a certain order of iteration. Is there any way to do this in code by extending Iterator?

Not directly. The iterator is made just to give you an item at time, avoiding to storing in memory and pass a whole list of values, which could be unfeasible at times.
Unless you have more knowledge on how the values are generated and which bounds have to be applied to the sorting of data, the only way is to get all elements from the iterator, store them in some list/vector/database, sort them and return another iterator using the sorted list.

You're being passed, as an argument, an instance of some concrete class which implements Iterator. You can't extend its class because its class is decided upon instantiation, which is done by the code that calls your method.
If you want to fail fast when the required order is not respected, try Guava's Ordering.isOrdered() method.
NB This will only work if your argument is an Iterable, rather than Iterator. You need it to be Iterable (an interface which allows you to retrieve the Iterator) so that you can iterate twice: once to check order, once to process.

Related

Concrete List type as parameter in java method

If there is a reason to make a parameter not generic, is that a good approach?
Let's say I know in the method there takes place only access of members of list but not insertion should I force the developers to pass an ArrayList.
public void method(ArrayList<Integer> list)
{
// ......
}
as you can see developers have to pass a list of type ArrayList otherwise they get error.
should I force the developers to pass an ArrayList.
IMO, no. The developer might use the list somewhere else. Only he knows the actual usage of the list and it should be up to him to choose the best list implementation. If there is no actual reason to enforce a specific implementation, you should always use the List interface.
Generally speaking, there are two good (albeit possibly rare) reasons I can think of to do this.
First, if you want to use a method that's only present in a specific implementation. ArrayList doesn't seem to have too many useful methods that aren't already specified by the List or even Collection interfaces, but it's still a possibility.
Second, which is a slight variation on the previous reason, is if you want to convey some performance expectations of your method. For example, both the ArrayList and LinkedList classes have a get(int) method. ArrayList's implementation works in constant time (O(1)), while LinkedList's is linearly dependent on the size of the list (O(n)). If your method relies heavily on this method, you may not want to allow calling it with a LinkedList.
The main issue with this is that the caller probably hasn't typed their List as an ArrayList, so even if they do have an ArrayList, they would probably have to write an explicit cast at every call-site. That would make the caller's code messier.
Another issue is that ArrayList is not the only class which implements List and supports random access in O(1) time. For example, Arrays.asList returns a java.util.Arrays$ArrayList object which is not an instance of java.util.ArrayList. Alternatively, for example if I want to implement a sparse List using a hashtable, such that get takes O(1) time but it's not an ArrayList, then I wouldn't be able to supply my list to this method even though it meets the performance requirements.
My solution would be to check the argument at runtime:
if(list instanceof LinkedList) {
// ...
}
Then you can either log a warning to inform about the performance issue, or (if you must be prescriptive), throw an IllegalArgumentException to say the method should not be called with a LinkedList. This means the caller's mistake would be detected at runtime rather than compile-time, but it should be detected the very first time it's tested, so that is no great loss.
Another option, of course, is to take an array instead of a list as your parameter. That won't be suitable for all purposes, but it's e.g. how the standard library's binarySearch method ensures it takes a sequence which supports random access in O(1) time.

Why don't we put the hasNext(), next() and other methods in Collection interface?

I am confused with a design problem in Java. It realized many abstract containers under the interface Collection and provides the method hasNext() and Next() along with class Iterator. What is the drawback if I put these methods directly under interface Collection and then overrides it in each subclass:
For example, I have already realized Next(); hasNext() method under class ArrayList. So what I wrote is
ArrayList ArrList=new ArrayList()
if(ArrList.hasNext())
new obj=ArrList.next();
}
returning the objects stored in ArrList.
So is it redundant to introduce Iterator class for the interface Collection? And what is the benefit to design ArrList.iterator(); if it's more covenient to set it up in interface?
Can I find any book to solve such oop-design problems(As the computer scientists described it)?
Thanks for your time.
The methods of the Iterator interface (next(), hasNext()) can't simply be added to the interface. An Iterator has a state which determines the next element that would be returned by the iterator.
If the Iterator methods were part of the Collection interface, you would need some additional method to reset this "built-in" iterator (in order to iterate again from the start of the Collection), and you would only have a single iterator for each Collection in any given time. A nested iteration as simple as the following snippet wouldn't be possible, since it requires two iterators :
List<Integer> list = ...
for (int i : list)
for (int j : list)
System.out.println(i+j);
Iterator stores a pointer to some element inside a collection. In case of ArrayList it is an index of the underlying array.
It allows you to say iterate over the collection in two separate threads simultaneously. If the pointer was a part of ArrayList, each of the threads would skip some of the elements.
An iterator is usually made to traversed once. In the Java collection library classes will fail if modifications are made to the underlying collection during a traversal of an iterator.
BTW, this question may be more appropriate for Programmers Stack Exchange which is dedicated to theoretical programming questions.
Let's assume for a moment that ArrayList did have hasNext and next methods, and so your code would compile. (You'd also need another method to tell the list you wanted to start over again.) That would mean that I could only have one iteration of the list active at a time, because the list itself contains the iteration state. That's just poor design; instead, we have the Iterator concept so that the state of the iteration is stored in the iterator, not the list, and we can have multiple iterators.
At the conceptual level: Collection represents a collection of objects. Adding methods for hasNext and next would turn it into a collection of objects along with another piece of state, a 'current object', as well as some concept of how to traverse the collection.
Since these are two separate ideas, it is best to divide them into separate structures that are implemented independently. In the case you speak of, that would be the Collection structure (which handles storage and structure for a collection of objects), and the Iterator structure (which handles position and traversal of some collection of objects).

java-how to manage multiple lists of data- in a single variable- with easy access to each list

I have a scenario where I have to work with multiple lists of data in a java app...
Now each list can have any number of elements in it... Also, the number of such lists is also not known initially...
Which approach will suit my scenario best? I can think of arraylist of list, or list of list or list of arraylist etc(ie combinations of arraylist + list/ arraylist+arraylist/list+list)... what I would like to know is--
(1) Which of the above (or your own solution) will be easiest to manage- viz to store/fetch data
(2) Which of the above will use the least amount of memory?
I would declare my variable as:
List<List<DataType>> lists = new ArrayList<List<DataType>>();
There is a slight time penalty in accessing list methods through a variable of an interface type, but this, I think, is more than balanced by the flexibility you have of changing the type as you see fit. (For instance, if you decided to make lists immutable, you could do that through one of the methods in java.util.Collections, but not if you had declared it to be an ArrayList<List<DataType>>.)
Note that lists will have to hold instances of some concrete class that implements List<DataType>, since (as others have noted) List is an interface, not a class.
List is an interface. ArrayList is one implementation of List.
When you construct a List you must choose a specific concrete type (e.g. ArrayList). When you use the list it is better to program against the interface if possible. This prevents tight coupling between your code and the specific List implementation, allowing you to more easily change to another List implementation later if you wish.
If you know a way to identify which list you will be dealing with, use a map of lists.
Map<String,List<?>> = new HashMap<String,List<?>>();
This way you would avoid having to loop through the outer elements to reach the actual list. Hash map performs better than an iterator.

What is the Iterable interface used for?

I am a beginner and I cannot understand the real effect of the Iterable interface.
Besides what Jeremy said, its main benefit is that it has its own bit of syntactic sugar: the enhanced for-loop. If you have, say, an Iterable<String>, you can do:
for (String str : myIterable) {
...
}
Nice and easy, isn't it? All the dirty work of creating the Iterator<String>, checking if it hasNext(), and calling str = getNext() is handled behind the scenes by the compiler.
And since most collections either implement Iterable or have a view that returns one (such as Map's keySet() or values()), this makes working with collections much easier.
The Iterable Javadoc gives a full list of classes that implement Iterable.
If you have a complicated data set, like a tree or a helical queue (yes, I just made that up), but you don't care how it's structured internally, you just want to get all elements one by one, you get it to return an iterator.
The complex object in question, be it a tree or a queue or a WombleBasket implements Iterable, and can return an iterator object that you can query using the Iterator methods.
That way, you can just ask it if it hasNext(), and if it does, you get the next() item, without worrying where to get it from the tree or wherever.
It returns an java.util.Iterator. It is mainly used to be able to use the implementing type in the enhanced for loop
List<Item> list = ...
for (Item i:list) {
// use i
}
Under the hood the compiler calls the list.iterator() and iterates it giving you the i inside the for loop.
An interface is at its heart a list of methods that a class should implement. The iterable interface is very simple -- there is only one method to implement: Iterator(). When a class implements the Iterable interface, it is telling other classes that you can get an Iterator object to use to iterate over (i.e., traverse) the data in the object.
Iterators basically allow for iteration over any Collection.
It's also what is required to use Java's for-each control statement.
The Iterable is defined as a generic type.
Iterable , where T type parameter represents the type of elements returned by the iterator.
An object that implements this interface allows it to be the target of the “foreach” statement. The for-each loop is used for iterating over arrays, collections.
read more -: https://examples.javacodegeeks.com/iterable-java-example-java-lang-iterable-interface/

What are the benefits of the Iterator interface in Java?

I just learned about how the Java Collections Framework implements data structures in linked lists. From what I understand, Iterators are a way of traversing through the items in a data structure such as a list. Why is this interface used? Why are the methods hasNext(), next() and remove() not directly coded to the data structure implementation itself?
From the Java website: link text
public interface Iterator<E> An
iterator over a collection. Iterator
takes the place of Enumeration in the
Java collections framework. Iterators
differ from enumerations in two ways:
Iterators allow the caller to remove
elements from the underlying
collection during the iteration with
well-defined semantics. Method names
have been improved. This interface is
a member of the Java Collections
Framework.
I tried googling around and can't seem to find a definite answer. Can someone shed some light on why Sun chose to use them? Is it because of better design? Increased security? Good OO practice?
Any help will be greatly appreciated. Thanks.
Why is this interface used?
Because it supports the basic operations that would allow a client programmer to iterate over any kind of collection (note: not necessarily a Collection in the Object sense).
Why are the methods... not directly
coded to the data structure
implementation itself?
They are, they're just marked Private so you can't reach into them and muck with them. More specifically:
You can implement or subclass an Iterator such that it does something the standard ones don't do, without having to alter the actual object it iterates over.
Objects that can be traversed over don't need to have their interfaces cluttered up with traversal methods, in particular any highly specialized methods.
You can hand out Iterators to however many clients you wish, and each client may traverse in their own time, at their own speed.
Java Iterators from the java.util package in particular will throw an exception if the storage that backs them is modified while you still have an Iterator out. This exception lets you know that the Iterator may now be returning invalid objects.
For simple programs, none of this probably seems worthwhile. The kind of complexity that makes them useful will come up on you quickly, though.
You ask: "Why are the methods hasNext(), next() and remove() not directly coded to the data structure implementation itself?".
The Java Collections framework chooses to define the Iterator interface as externalized to the collection itself. Normally, since every Java collection implements the Iterable interface, a Java program will call iterator to create its own iterator so that it can be used in a loop. As others have pointed out, Java 5 allows us to direct usage of the iterator, with a for-each loop.
Externalizing the iterator to its collection allows the client to control how one iterates through a collection. One use case that I can think of where this is useful is when one has an an unbounded collection such as all the web pages on the Internet to index.
In the classic GoF book, the contrast between internal and external iterators is spelled out quite clearly.
A fundamental issue is deciding which party conrols the iteration, the iterator or the client that uses the iterator. When the client controls the iteration, the iterator is called an external iterator, and when the iterator controls it, the iterator is an internal iterator. Clients that use an external iterator must advance the traversal and request the next element explicitly from the iterator. In contrast, the client hands an internal iterator an operation to perform, and the iterator applies that operation to every element ....
External iterators are more flexible than internal iterators. It's easy to compare two collections for equality with an external iterator, for example, but it's practically impossible with internal iterators ... But on the other hand, internal iterators are easier to use, because they define the iteration logic for you.
For an example of how internal iterators work, see Ruby's Enumerable API, which has internal iteration methods such as each. In Ruby, the idea is to pass a block of code (i.e. a closure) to an internal iterator so that a collection can take care of its own iteration.
it is important to keep the collection apart from the pointer. the iterator points at a specific place in a collection, and thus is not an integral part of the collection. this way, for an instance, you can use several iterators over the same collection.
the down-side of this seperation is that the iterator is not aware to changes made to the collection it iterates on. so you cannot change the collection's structure and expect the iterator to continue it's work without "complaints".
Using the Iterator interface allows any class that implements its methods to act as iterators. The notion of an interface in Java is to have, in a way, a contractual obligation to provide certain functionalities in a class that implements the interface, to act in a way that is required by the interface. Since the contractual obligations must be met in order to be a valid class, other classes which see the class implements the interface and thus reassured to know that the class will have those certain functionalities.
In this example, rather than implement the methods (hasNext(), next(), remove()) in the LinkedList class itself, the LinkedList class will declare that it implements the Iterator interface, so others know that the LinkedList can be used as an iterator. In turn, the LinkedList class will implement the methods from the Iterator interface (such as hasNext()), so it can function like an iterator.
In other words, implementing an interface is a object-oriented programming notion to let others know that a certain class has what it takes to be what it claims to be.
This notion is enforced by having methods that must be implemented by a class that implements the interface. This makes sure that other classes that want to use the class that implements the Iterator interface that it will indeed have methods that Iterators should have, such as hasNext().
Also, it should be noted that since Java does not have multiple inheritance, the use of interface can be used to emulate that feature. By implementing multiple interfaces, one can have a class that is a subclass to inherit some features, yet also "inherit" the features of another by implementing an interface. One example would be, if I wanted to have a subclass of the LinkedList class called ReversibleLinkedList which could iterate in reverse order, I may create an interface called ReverseIterator and enforce that it provide a previous() method. Since the LinkedList already implements Iterator, the new reversible list would have implemented both the Iterator and ReverseIterator interfaces.
You can read more about interfaces from What is an Interface? from The Java Tutorial from Sun.
Multiple instances of an interator can be used concurrently. Approach them as local cursors for the underlying data.
BTW: favoring interfaces over concrete implementations looses coupling
Look for the iterator design pattern, and here: http://en.wikipedia.org/wiki/Iterator
Because you may be iterating over something that's not a data structure. Let's say I have a networked application that pulls results from a server. I can return an Iterator wrapper around those results and stream them through any standard code that accepts an Iterator object.
Think of it as a key part of a good MVC design. The data has to get from the Model (i.e. data structure) to the View somehow. Using an Iterator as a go-between ensures that the implementation of the Model is never exposed. You could be keeping a LinkedList in memory, pulling information out of a decryption algorithm, or wrapping JDBC calls. It simply doesn't matter to the view, because the view only cares about the Iterator interface.
An interesting paper discussing the pro's and con's of using iterators:
http://www.sei.cmu.edu/pacc/CBSE5/Sridhar-cbse5-final.pdf
I think it is just good OO practice. You can have code that deals with all kinds of iterators, and even gives you the opportunity to create your own data structures or just generic classes that implement the iterator interface. You don't have to worry about what kind of implementation is behind it.
Just M2C, if you weren't aware: you can avoid directly using the iterator interface in situations where the for-each loop will suffice.
Ultimately, because Iterator captures a control abstraction that is applicable to a large number of data structures. If you're up on your category theory fu, you can have your mind blown by this paper: The Essence of the Iterator Pattern.
Well it seems like the first bullet point allows for multi-threaded (or single threaded if you screw up) applications to not need to lock the collection for concurrency violations. In .NET for example you cannot enumerate and modify a collection (or list or any IEnumerable) at the same time without locking or inheriting from IEnumerable and overriding methods (we get exceptions).
Iterator simply adds a common way of going over a collection of items. One of the nice features is the i.remove() in which you can remove elements from the list that you are iterating over. If you just tried to remove items from a list normally it would have weird effects or throw and exception.
The interface is like a contract for all things that implement it. You are basically saying.. anything that implements an iterator is guaranteed to have these methods that behave the same way. You can also use it to pass around iterator types if that is all you care about dealing with in your code. (you might not care what type of list it is.. you just want to pass an Iterator) You could put all these methods independently in the collections but you are not guaranteeing that they behave the same or that they even have the same name and signatures.
Iterators are one of the many design patterns available in java. Design patterns can be thought of as convenient building blocks, styles, usage of your code/structure.
To read more about the Iterator design pattern check out the this website that talks about Iterator as well as many other design patterns. Here is a snippet from the site on Iterator: http://www.patterndepot.com/put/8/Behavioral.html
The Iterator is one of the simplest
and most frequently used of the design
patterns. The Iterator pattern allows
you to move through a list or
collection of data using a standard
interface without having to know the
details of the internal
representations of that data. In
addition you can also define special
iterators that perform some special
processing and return only specified
elements of the data collection.
Iterators can be used against any sort of collection. They allow you to define an algorithm against a collection of items regardless of the underlying implementation. This means you can process a List, Set, String, File, Array, etc.
Ten years from now you can change your List implementation to a better implementation and the algorithm will still run seamlessly against it.
Iterator is useful when you are dealing with Collections in Java.
Use For-Each loop(Java1.5) for iterating over a collection or array or list.
The java.util.Iterator interface is used in the Java Collections Framework to allow modification of the collection while still iterating through it. If you just want to cleanly iterate over an entire collection, use a for-each instead, but a upside of Iterators is the functionality that you get: a optional remove() operation, and even better for the List Iterator interface, which offers add() and set() operations too. Both of these interfaces allow you to iterate over a collection and changing it structurally at the same time. Trying to modify a collection while iterating through it with a for-each would throw a ConcurrentModificationException, usually because the collection is unexpectedly modified!
Take a look at the ArrayList class
It has 2 private classes inside it (inner classes)
called Itr and ListItr
They implement Iterator and the ListIterator interfaces respectively
public class ArrayList..... { //enclosing class
private class Itr implements Iterator<E> {
public E next() {
return ArrayList.this.get(index++); //rough, not exact
}
//we have to use ArrayList.this.get() so the compiler will
//know that we are referring to the methods in the
//enclosing ArrayList class
public void remove() {
ArrayList.this.remove(prevIndex);
}
//checks for...co mod of the list
final void checkForComodification() { //ListItr gets this method as well
if (ArrayList.this.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
}
private class ListItr extends Itr implements ListIterator<E> {
//methods inherted....
public void add(E e) {
ArrayList.this.add(cursor, e);
}
public void set(E e) {
ArrayList.this.set(cursor, e);
}
}
}
When you call the methods iterator() and listIterator(), they return
a new instance of the private class Itr or ListItr, and since these inner classes are "within" the enclosing ArrayList class, they can freely modify the ArrayList without triggering a ConcurrentModificationException, unless you change the list at the same time (conccurently) through set() add() or remove() methods of the ArrayList class.

Categories