Why? And what the best way to move iterator items pointer to the first position?
Why?
Because if you force iterator to have a reset method every iterator has to have a reset method. That gives every iterator writer extra work. Plus some iterators are really hard (or really expensive) to reset, and you wouldn't want users to call reset on them. Iterators over files or streams are good examples.
what the best way to move iterator items pointer to the first position?
Create a new iterator. It's rarely more expensive than the reset.
Once you read a stream, you can't re-read it without opening the source again. That's how streams and iterators work.
The best way is to create a new one!
This is a general tendency adopted in JCF - keep the interface minimalistic , unless that makes some feature extremely difficult to work. This is the reason why you do not have separate interfaces for semantics like immutable collections, fixed-size collections ..
As to why then a remove(Object) is provided ( as optional ) - Not providing this would make it impossible to safely remove an item from a collection while iterating over the collection - there is nothing that makes providing a reset() so compulsary.
Again , why there is a separate ListIterator() ( providing methods like previous() and previousIndex() ) - With a List interface , the main functionality while it is being used is the ability to layout the elements wrt an index, and to be able to access them with an index-order , whether fixed or random order. This is not the case with other collections.Not providing this interface for a List will make it very difficult if not impossible to work smoothly with a list.
Tip: create your iterator variable as a function instead, then you can consume it as many times are you want. This only works if the underlying logic is repeatable.
Example in Scala (Java similar but I don't have a Java REPL handy)
def i = (1 to 100) iterator // i is our iterator
i.grouped(50) foreach println // prints two groups
i.grouped(50) foreach println // prints same two groups again
Related
I was wondering about the Java 8 streams (Stream<E>), they have the following methods:
forEach(Consumer<? super E> action)
forEachOrdered(Consumer<? super E> action)
What were the arguments against not supplying the following signature?
forEachOrdered(BiConsumer<Integer, ? super E> action)
Which would then return the index of the item in the stream and the item itself.
With this overload it would be possible to actually use the index in case the stream was ordered.
I am really curious to see what the arguments are against it.
Edit, the same actually holds for Iterator<E> with forEachRemaining, and possibly more classes.
If none of the classes provide such option, then I suspect it has been considered for Java 8 and denied.
indexing every element requires a sequential assignment of the indexes. this would defeat the point of parallel operations, since each operation would have to synchronize to get its index.
Streams and Iterators do not have to be finite. Both Stream::generate
and Stream::iterate return infinite Streams. How would you handle indexing with an infinite stream? Let the index overflow to negative numbers? Use a BigInteger (and potentially run out of memory)?
There isn't a good solution to handling indexing for infinite streams, so the designers (correctly, in my opinion) left it out of the API.
Adding a single method providing an index would require all implementation methods to be doubled to have one maintaining an index and one without. There’s more to it than visible in the API. If you are curious you may look at the type tree of the internal interface java.util.stream.Sink<T> to get an idea. All of them would be affected. The alternative would be to always maintain an index even if it is not required.
And it adds an ambiguity. Does the index reflect the source index, i.e. does not change on filtering, or is it a position in the final stream? On the other hand you can always insert a mapping from an item type to a type holding the item and an index at any places in the chain. This would clear the ambiguity. And the limitations to that solution are the same that a JRE provided solution would have.
In case of an Iterator the answer is even simpler. Since forEachRemaining must be provided as a default interface method it cannot add the maintenance of an index. So at the time it is invoked, it doesn’t know how many items have been consumed so far. And starting the count with zero at that time, ignoring all previous items would be a feature that a lot of developers would question even more.
I have read all above answers, however, personally i disagree with them. I think some method(e.g. indexed()) should be added and it can be executed sequentially, even in parallel stream because this method will be verify fast, no need to execute in parallel. You can add 'index' by map. for example:
List<String> list = N.asList("a", "b", "c");
final AtomicLong idx = new AtomicLong(0);
list.stream().map(e -> Indexed.of(idx.getAndIncrement(), e)).forEach(N::println);
Or you can use third library: abacus-common, the code will be:
List<String> list = N.asList("a", "b", "c");
Stream.of(list).indexed().forEach(N::println);
// output:
// [0]=a
// [1]=b
// [2]=c
Disclosure: I'm the developer of abacus-common.
The question might be pretty vague I know. But the reason I ask this is because the class must have been made with some thought in mind.
This question came into my mind while browsing through a few questions here on SO.
Consider the following code:
class A
{
private int myVar;
A(int varAsArg)
{
myVar = varAsArg;
}
public static void main(String args[])
{
List<A> myList = new LinkedList<A>();
myList.add(new A(1));
myList.add(new A(2));
myList.add(new A(3));
//I can iterate manually like this:
for(A obj : myList)
System.out.println(obj.myVar);
//Or I can use an Iterator as well:
for(Iterator<A> i = myList.iterator(); i.hasNext();)
{
A obj = i.next();
System.out.println(obj.myVar);
}
}
}
So as you can see from the above code, I have a substitute for iterating using a for loop, whereas, I could do the same using the Iterator class' hasNext() and next() method. Similarly there can be an example for the remove() method. And the experienced users had commented on the other answers to use the Iterator class instead of using the for loop to iterate through the List. Why?
What confuses me even more is that the Iterator class has only three methods. And the functionality of those can be achieved with writing a little different code as well.
Some people might argue that the functionality of many classes can be achieved by writing one's own code instead of using the class made for the purpose. Yes,true. But as I said, Iterator class has only three methods. So why go through the hassle of creating an extra class when the same job can be done with a simple block of code which is not way too complicated to understand either.
EDIT:
While I'm at it, since many of the answers say that I can't achieve the remove functionality without using Iterator,I would just like to know if the following is wrong, or will it have some undesirable result.
for(A obj : myList)
{
if(obj.myVar == 1)
myList.remove(obj);
}
Doesn't the above code snippet do the same thing as remove() ?
Iterator came long before the for statement that you show in the evolution of Java. So that's why it's there. Also if you want to remove something, using Iterator.remove() is the only way you can do it (you can't use the for statement for that).
First of all, the for-each construct actually uses the Iterator interface under the covers. It does not, however, expose the underlying Iterator instance to user code, so you can't call methods on it.
This means that there are some things that require explicit use of the Iterator interface, and cannot be achieved by using a for-each loop.
Removing the current element is one such use case.
For other ideas, see the ListIterator interface. It is a bidirectional iterator that supports inserting elements and changing the element under the cursor. None of this can be done with a for-each loop.
for(A obj : myList)
{
if(obj.myVar == 1)
myList.remove(obj);
}
Doesn't the above code snippet do the same thing as remove() ?
No, it does not. All standard containers that I know of will throw ConcurrentModificationException when you try to do this. Even if it were allowed to work, it is ambiguous (what if obj appears in the list twice?) and inefficient (for linked lists, it would require linear instead of constant time).
The foreach construct (for (X x: list)) actually uses Iterator as its implementation internally. You can feed it any Iterable as a source of elements.
And, as others already remarked: Iterator is longer in Java than foreach, and it provides remove().
Also: how else would you implement your own provider class (myList in your example)? You make it Iterable and implement a method that creates an Iterator.
For one thing, Iterator was created way before the foreach loop (shown in your code sample above) was introduced into Java. (The former came in Java2, the latter only in Java5).
Since Java5, indeed the foreach loop is the preferred idiom for the most common scenario (when you are iterating through a single Iterable at a time, in the default order, and do not need to remove or index elements). Note though that the foreach uses an iterator in the background for standard collection classes; in other words it is just syntactic sugar.
Iterator, listIterator both are used to allow different permission to user, like list iterator have 9 methods but iterator have only 3 methods, but have remove functionality which you can't achieve with for loop. Enumeration is another thing which is also used to give only read permissions.
Iterator is an implementation of the classical GoF design pattern. In that way you can achieve clear behaviour separation from the 'technical code' which iterates (the Iterator) and your business code.
Imagine you have to change the 'next' behaviour (say, by getting not the next element but the next EVEN element). If you rely only on for loops you will have to change manually every single for loop, in a way like this
for (int i; i < list.size(); i = i+2)
while if you use an Iterator you can simply override/rewrite the "next()" and "hasNext()" methods and the change will be visible everywhere in your application.
I think answer to your question is abstraction. Iterator is written because to abstract iterating over different set of collections.
Every collection has different methods to iterate over their elements. ArrayList has indexed access. Queues has poll and peek methods. Stack has pop and peek.
Usually you only need to iterate over elements so Iterator comes into play. You do not care about which type of Collection you need to iterate. You only call iterator() method and user Iterator object itself to do this.
If you ask why not put same methods on Collection interface and get rid of extra object creation. You need to know your current position in collection so you can not implement next method in Collection because you can not use it on different locations because every time you call next() method it will increment index (simplifying every collection has different implementation) so you will skip some objects if you use same collection at different places. Also if collection support concurrency than you can not write a multi-thread safe next() method in collection.
It is usually not safe to remove an object from collection iterating by other means than iterator. Iterator.remove() method is safest way to do it. For ArrayList example:
for(int i=0;i
Main Question:
I'm seeking some way to give an object within a LinkedList a reference to itself within the list so that it can (efficiently) remove itself from said list (Without sorting through the list looking for itself. I'd like it to just directly cut itself from the list and tie the previous and next items together.).
Less Necessary Details:
I've done a reasonable amount of googling and not found anything other than people advising not to use circular references.
I'd like to do this as I'm designing a game, and in the game objects can implement various interfaces which allow them to be in various lists which are looped through in a prioritized manner. A single object might be in a draw loop, a loop which steps it through the frames of its animation, a high priority logic loop, and a low priority logic loop all at the same time. I would like to implement a removeFrom|TypeOfLoop| method in each appropriate interface so that if an object decides that it no longer needs to be in a loop it can directly remove itself. This keeps the objects that do the actual looping pleasantly simple.
Alternatively, If there is no way to do this, I'm thinking of implementing a flagging system where the list checks to see if each item wants to be removed based on a variable within the item. However, I dislike the idea of doing this enough to possibly just make my own LinkedList that is capable of removing by reference.
I did this recently. I was looking for an O(1) add O(1) remove lock-free Collection. Eventually I wrote my own Ring because I wanted a fixed-size container but you may find the technique I used for my first attempt of value.
I don't have the code in front of me but if memory serves:
Take a copy of Doug Lea's excellent Concurrent Doubly LinkedList and:
Expose the Node class. I used an interface but that is up to you.
Change the add, offer ... methods to return a Node instead of boolean. It is now no longer a java Collection, but see my comment later.
Expose the delete method of the Node class or add a remove method that takes a Node.
You can now remove elements from the list in O(1) time, and it is Lock Free.
Added
Here's an implementation of the remove(Node) method taken from his Iterator implementation. Note that you have to keep trying until you succeed.
public void remove(Node<E> n) {
while (!n.delete() && !n.isDeleted())
;
}
I think your alternative is much better than letting the item remove itself from the loop. It reduces the responsibilities of the objects in the list, and avoids circular references.
Moreover, You could use Guava's Iterables.filter() method and iterate over a filtered list, rather than checking explicitely if the object should be rendered or not at each iteration.
Even if what you want to do was possible, you would get a ConcurrentModificationException when removing an object from the list while iterating on it. The only way to do that is to remove the current object from the iterator.
If you're using LinkedList, there's no more efficient way to remove an item than to iterate over it and do iterator.remove() when you find your element.
If you're using google collections or guava, you can do it in a oneliner:
Iterables.removeIf(list.iterator(), Predicates.equalTo(this));
The easiest way would be changing your algorithm to use Iterator to iterate over List objects and use Iterator.remove() method to remove current element.
I need to filter a List of size 1000 or more and get a sublist out of it.
I dont want to use an iterator.
1) At present I am iterating the List and comparing it using Java. This is time consuming task. I need to increase the performance of my code.
2) I also tried to use Google Collections(Guava), but I think it will also iterate in background.
Predicate<String> validList = new Predicate<String>(){
public boolean apply(String aid){
return aid.contains("1_15_12");
}
};
Collection<String> finalList =com.google.common.collect.Collections2.filter(Collection,validList);
Can anyone suggest me how can I get sublist faster without iterating or if iterator is used I will get result comparatively faster.
Consider what happens if you call size() on your sublist. That has to check every element, as every element may change the result.
If you have a very specialized way of using your list which means you don't touch every element in it, don't use random access, etc, perhaps you don't want the List interface at all. If you could tell us more about what you're doing, that would really help.
List is an ordered collection of objects. So You must to iterate it in order to filter.
I enrich my comment:
I think iterator is inevitable during filtering, as each element has to be checked.
Regarding to Collections2.filter, it's different from simple filter: the returned Collection is still "Predicated". That means IllegalArgumentException will be thrown if unsatisfied element is added to the Collection.
If the performance is really your concern, most probably the predicate is pretty slow. What you can do is to Lists.partition your list, filter in parallel (you have to write this) and then concatenate the results.
There might be better ways to solve your problem, but we would need more information about the predicate and the data in the List.
Often there is the need to setup an ArrayList<>. One of the constructors takes a collection, but there is no constructor that takes an iterator.
What if I have an iterator? Is there a way to "reach up" to the collection that offers the iterator in order to use the ArrayList<> constructor?
Specifically I have the iterator offered by PropertiesConfiguration.getKeys() which is part of org.apache.commons.
There's no such thing, an Iterator's Collection. An Iterator can be created independently of a Collection. It can be obtained from any Iterable, or you can even create a class implementing an iterator.
However, you can obtain an ArrayList from an Iterator by iterating it and adding its elements one by one:
Iterator<X> it = ...;
List<X> list = new ArrayList<X>();
while (it.hasNext()) {
list.add(it.next());
}
Note, however, that this cannot be done reliably for every possible iterator, since there's the possibility that an iterator will iterate forever, thus causing an infinite loop and most probably an OutOfMemoryError.
I'd suggest you take a look at Google Guava, an utility library from Google. It has a class called Lists, which allows you to do the following:
Iterator<X> it = ...;
List<X> list = Lists.newArrayList(it);
The library has tons of methods extremely useful for everyday Java coding. It contains mostly everything you want but cannot find in the standard Java 6 API.
There is no truly general way to do this, because in Java, Iterator is just an interface with three methods: next, hasNext and remove.
When you obtain an iterator, you use a factory method that gives you an instance of some class implementing the interface. If you know the specific class, you can look at its documentation or source to find if there is a way to find the collection it is iterating over.
But there are many such classes. In the case of ArrayList, look in the source code to see what kind of iterator you are getting.
EDIT:
Here is the source code for ArrayList in Open JDK 7: http://www.docjar.com/html/api/java/util/ArrayList.java.html
The iterator over an ArrayList is an instance of the private inner class Itr. This should not be too surprising. The iterator comes from a factory method, after all, so you're really not supposed to know what kind of iterator you are getting. In fact, if you were able to get the class of this instance and access its methods (say, via reflection) you would be doing a bad thing. This iterator is part of the (internal) implementation of the ArrayList class and (as #merryprankster points out) can change in the future.
I don't know if its possible, but in my opinion, a such function should not exist because an iterator may not come from a collection. For example, one could create an iterator which chains over multiple collections !