How to simulate a pointer to LinkedList element in Java? - java

I need an object, that
points to element of linked list
can be iterated to next
can be cloned
all operations should be O(1)
I don't see proofs, that ListIterator complies these requirements. Particularly, I don't see it is Cloneable.

There is no class that fulfill all the criteria for java.util.LinkedList. You need to implement your own linked list for that.

java.util.LinkedList and it's iterators have limitations. Assigning an iterator only creates another reference to the same iterator object, so not "cloneable" assuming that's what you mean by "cloneable". If you create multiple iterators to a list, if any nodes are added or removed from a list, all iterators (except one used for add) will be invalidated. There's no equivalent of C++ std::list::splice(), which can move one or mode nodes within a list or from list to list.

Related

Why can't we manually iterate through a LinkedList?

LinkedList is a data structure, in which each element is coupled with a link to its next element.
So, in theory, this data structure is made for freely iterating through a list, in whichever direction, while performing whatever operations (except, maybe, deleting the element you're currently at).
However, in application, this isn't true. Returning an Iterator from a LinkedList is subject to the general Iterator rules (i.e. no modifying while iterating), and even creating a ListIterator, an improved Iterator, which allows modifying the next/previous element of the iterator, and let's you go forward/backward dynamically, still has severe limitations:
You can't delete elements from the beginning of the list if you're not currently there, and neither can you add elements to the end of the list, unless you're currently there.
So, is there a way to iterate freely through a LinkedList while performing whatever modifications to the list? And if not, why isn't there one? Shouldn't it be one of the main goals of this data structure to realize it?
The choice to make all Iterators failfast was a design decision, just that and nothing more.
Nothing stops you to take the code and starting from that, build a NotSoFailFastIterator for yourself if you think you can use it. However I think you'll quickly revert from using it once yoy see its behaviour and its results in usage scenarios where there's really lots of concurrent activity going on on the underlying List of your iterator.
This behavior is not specific to LinkedLists. When you iterate over a List (any List) with a ListIterator, you can only make structural changes (adding or removing elements) in the current position of the iterator. Otherwise, continuing to use the iterator after a structural change of the List may yield unexpected results.
For adding elements to the start or end of the LinkedList, you have addFirst and addLast methods. You don't have to iterate over the List in order to do that.
A ListIterator instance maintains a state that allows it to locate the next and previous elements as well as support other operations (remove the current element, add an element at the current position). If you make a structural change to a List not via the ListIterator, the state of the iterator may become invalid, leading to unexpected results. Therefore all structural changes must be made via the ListIterator.
I guess that the LinkedList class could supply an implementation of a more complex iterator that supports operations such as addFirst and addLast. I'm not sure how useful that would have been, and whether it would justify the added complexity.
If you want to iterate freely use array or list. Linked lists are meant to be traversed and access the data useful in dynamic allocation of the memory to the data.
When you have a linked list datastructure, you can add or remove at a particular node, when your cursor is pointing to the right node where you want to add or remove.
Inserts the specified element into the list (optional operation). The
element is inserted immediately before the element that would be
returned by next(), if any, and after the element that would be
returned by previous(), if any. The new element is inserted before
the implicit cursor: a subsequent call to next would be unaffected,
and a subsequent call to previous would return the new element. (This
call increases by one the value that would be returned by a call to
nextIndex or previousIndex.)
ListIterator
Instead if its a array structure, then you access by index , and it is possible to add or remove at a particular index limited , by the length of the array. ArrayList does that.

Java Collection (LinkedList Concepts)

When I declare LinkedList like:
List<String> names = new LinkedList<String>();
it does not support any of the LinkedList's special methods (ex: names.peekLast(), names.pollFirst() )
But when I declare like:
LinkedList<String> names = new LinkedList<String>();
then it supports these methods.
Yes, it is obvious that reason is the reference, as LinkedList contains that's methods and List does not have!
But my question is that when I want to work with LinkedList, which one is better and correct? Or what is the usage of them?
If you need to use LinkedList methods that don't exist in List, you should use a LinkedList reference (you could use a List reference and cast to LinkedList in order to call LinkedList specific methods, but that would make less sense).
Otherwise, it is preferable to use the List interface for holding the reference, since it makes your code more generic, since it won't depend on any specific List implementation.
Well, List is basically backed by an array which is usually bigger than the current number of items. The elements are put in an array, and a new array is created when the old one runs out of space. This is fast for access by index, but slow at removing or inserting elements within the list or at the start. Adding/removing entries at the end of the list is reasonably cheap.
LinkedList is a doubly-linked list - each node knows its previous entry and its next one. This is fast for inserting after/before a particular node (or the head/tail), but slow at access by index.
LinkedList will usually take more memory than List because it needs space for all those next/previous references - and the data will probably have less locality of reference, as each node is a separate object. On the other hand, a List can have a backing array which is much larger than its current needs.
Reference from Difference between List<T> and LinkedList<T>
You can also refer to oracle docs
Linked List
All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.
List
The List interface provides four methods for positional (indexed) access to list elements. Lists (like Java arrays) are zero based. Note that these operations may execute in time proportional to the index value for some implementations (the LinkedList class, for example). Thus, iterating over the elements in a list is typically preferable to indexing through it if the caller does not know the implementation.
Well there is very simple explanation regarding that is List<> is like array which is making new array when its running out of space. And LinkedList<> is like doubly-linked list where each an every node will have link of previous node as well as next node.
More of that you can search from oracle docs
https://docs.oracle.com/javase/7/docs/api/java/util/List.html
and
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
You can differentiate by your self. :)

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).

Difference Between Iterator remove vs ArrayList remove?

To remove element from ArrayList, we can use-
Iterator remove() is used while iteration.
For ArrrayList remove() no iteration required.
Syntax is different in those cases. So
Do both use same logic internally?
Is there any more difference than logic?
Which one is better?
Any detailed explanation/link is highly appreciated.
An iterator might throw ConcurrentModificationException if an element is removed from the underlying collection in another way than the iterator's own remove() method.
So if you need to remove elements while iterating over a collection, you're allowed to do that with Iterator.remove() but you can't do that with Collection.remove() without risking to get an exception.
remove is a method that should be implemented (if no, it should throw UnsupportedOperationException) by all objects that are Iterable (implement interface Itarable). The way it works depends always on the object that implements it.
That means an ArrayList can implement it in a totally different way then i.e. LinkedList.
Removing object in Iterator requires You to iterate (find) the object You want to remove.
Using a remove method in ArrayList (there is no delete I can see in Javadoc: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html) finds the object for You and deletes it. It actually shifts objects in an underlying arrays to fill the "gap" You created by removing the object, so if You want to remove items in a list often, You could use LinkedList Instead.
Additionally while You are iterating through a list, You will cause an exception if You want to modify the collection in some other way than via iterator methods.
The exact answers to Your questions are:
1.No they use diferent logic, and additionally Iterator might even not allow to delete object (UnsupportedOperationException)
2.You cannot remove object by ArrayList remove while You are itereating, and to remove object at position 4 in ArrayList by using Iterator You would have to iterate 4 times "manually".
3.It depends whether You allready know what object do You want to remove, or first You check all the objects and decide whether to delete, during the iteration process. Additionally - If You want to delete objects often, You better use LinkedList, instead of ArrayList.

Exact meaning of the sentence.."Iterator itr=al.iterator(); "

Iterator itr=al.iterator();
how does this line eactly work? does it just store the arraylist al in iterator? Can anyone pls give me a detailed explanation.
Thanks in advance.
From the documentation :
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.
http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
Basically the iterator maintains a position for iterating over a collection. It can be used to iterate over a collection, with the option of modifying the collection while iterating over it without a ConcurrentModificationException.
Answer:
Returns an iterator over the elements in this list in proper sequence.
Before you can access a collection through an iterator, you must obtain one. Each of the collection classes provides an iterator( ) method that returns an iterator to the start of the collection. By using this iterator object, you can access each element in the collection, one element at a time.

Categories