ListIterator previous method not working - java

package wrap;
import java.util.*;
public class ArrayListDemo {
public static void main(String [] args){
ArrayList<String> a=new ArrayList<String>();
a.add("B");
a.add("C");
a.add("D");
ListIterator<String> i=a.listIterator();
while(i.hasPrevious()){
System.out.println(i.previous());
}
}
}
The program works fine for hasNext() and next() methods but for hasPrevious() and previous() it displays a message as below::
<terminated> ArrayListDemo [Java Application] C:\Program Files (x86)\Java\jre7\bin\javaw.exe (28-Oct-2013 3:20:35 PM)

From the doc :
public ListIterator<E> listIterator()
Returns a list iterator over the elements in this list (in proper
sequence).
and
boolean hasPrevious()
Returns true if this list iterator has more elements when traversing
the list in the reverse direction.
Because the iterator is in the first position, hasPrevious() will return false and hence the while loop is not executed.
a's elements
"B" "C" "D"
^
|
Iterator is in first position so there is no previous element
If you do :
ListIterator<String> i=a.listIterator(); <- in first position
i.next(); <- move the iterator to the second position
while(i.hasPrevious()){
System.out.println(i.previous());
}
It will print "B" because you're in the following situation :
a's elements
"B" "C" "D"
^
|
Iterator is in second position so the previous element is "B"
You could also use the method listIterator(int index). It allows you to place the iterator at the position defined by index.
If you do :
ListIterator<String> i=a.listIterator(a.size());
It will print
D
C
B

Since you get the default ListIterator for the list, it starts with the first element, which is why hasPrevious() returns false and the while loop is exited. If you want to traverse the list in the reverse order, get the ListIterator from the last index and traverse backwards using the hasPrevious() and previous() methods.
ListIterator<String> i = a.listIterator(a.size()); // Get the list iterator from the last index
while (i.hasPrevious()) {
System.out.println(i.previous());
}

ListIterator<String> i=a.listIterator();
initially iterator i will point to index of 0
You are at index 0 so there is no previous element.

It will start at the front of the list and thus nothing is before that point. If you want to use these methods, use a ListIterator.
Docs.

You gave to reach to the end of the list or anywhere in between to traverse back. There is no previous element to element at index 0.
Eg
System.out.println("Elements in forward directiton");
while(i.hasNext()){
System.out.println(i.next());
}
System.out.println("Elements in backward directiton");
while(i.hasPrevious()){
System.out.println(i.previous());
}

As said by others, You pointer is still pointing to first element in List so -1 is not possible.
List of size n will have 1,2 ....n-1 as index.
n-1 is not -1.
THis is the reason why hasPrevious and previous are not working for you.
Cheers.

Related

Why can't I reuse an iterator?ListIterator class initially with reference "itr",and is not accessible for another iteration.Can anyonehelpmewith this?

import java.util.*;
public class Main
{
public static void main(String[] args)
{
ArrayList <Integer> Array_List = new ArrayList();
Array_List.add(100);
Array_List.add(200);
//A listiterator to check previous element accessing
ListIterator <Integer> itr =Array_List.listIterator();
//Accessing and printing elements with hasNext() method
while(itr.hasNext()){
System.out.println("Index of elements : "+itr.nextIndex()+
" and element is "+itr.next()+" ");
}
System.out.println();
Array_List.add(1,250);
Array_List.remove(2);
//Accessing using the same iterator reference to print
previous elements
while(itr.hasPrevious())
{
System.out.println("I can access index but elements are not printed
here...");
System.out.println("Index of previous element is
:"+itr.previousIndex());
System.out.println(itr.previous());}
}
}
Output:
Index of elements : 0 and element is 100
Index of elements : 1 and element is 200
I can access index but elements are not printed here...
Index of previous element is :1
Iterators are invalidated as soon as you modify the backing list any way other than using the iterator itself.
...if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
These lines break your iterator:
Array_List.add(1,250);
Array_List.remove(2);
You will need to create a new, fresh iterator.

Why cant I add to ListIterator while iterating over it?

Im trying to add to a ListIterator while iterating over it but when checking if it worked hasNext() always returns false.
As javadoc states that a ListIterator is "An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list." however when Im trying to add I'm neither getting an Error message nor is the ListIterator getting a new Element.
public void foo() {
List<String> bar = new ArrayList<String>();
bar.add("foobar");
ListIterator<String> quux = bar.listIterator();
while(quux.hasNext()) {
if(quux.next().equals("foobar")) {
quux.add("baz");
}
}
}
At the end of this funtion I expect the ListIterator to contain the new String "baz". However when I call the hasNext() method it returns false. The program even got past the if-Statement it just turns out, that the add-method doesnt do what its supposed to do.
Your code works (after fixed the missed () after new ArrayList<String> and replaced == with the correct method to compare strings, equals:
import java.util.*;
public class test
{
public static void main(String[] args) {
List<String> bar = new ArrayList<String>();
bar.add("foobar");
ListIterator<String> quux = bar.listIterator();
while(quux.hasNext()) {
if(quux.next().equals("foobar")) {
quux.add("baz");
}
}
System.out.println(bar);
}
}
returns:
[foobar, baz]
As you can see, baz were inserted.
It seems that you expect to be able to fetch the added element with next():
nor is the ListIterator getting a new Element
[...]
At the end of this funtion I expect the ListIterator to contain the new String "baz". However when I call the hasNext() method it returns false
However, the JavaDoc for
ListIterator.add() explicitly states that this is not the case:
The new element is inserted before the implicit cursor: a subsequent call to next would be unaffected
If you want to include the element in the iteration you can rewind the list iterator by one position:
if(quux.next().equals("foobar")) {
quux.add("baz");
quux.previous();
}

Deleting random elements of a list while going through the list

From what I read, it is safe to remove elements while iterating through a list. (instead of using the simple for each loop).
Suppose I have a list of elements, and I want to visit all of the elements, but while I visit each element, I will visit its neighbours (note that I have a map for each element which will give me its neighbours), thus I will
have to remove other elements from the original list. Thus I cannot use
iterator.remove().
What is a good way to do this, that is to say, remove elements from the list that I am going through without being at the position with the iterator?
One idea I had was the following, have my elements in a map, with value as
a boolean, (true for visited, and false otherwise).
Thus, I go through my list, and for each element i set it visited true, and if one if its neighbours I also see while visiting that element, I will also set them as true.
Use a for loop instead of a foreach to iterate over the items. Then remove as you see fit. Here is an example of removing even elements from the List
import java.util.List;
import java.util.ArrayList;
class Test {
public static void main(String[] args){
final List<Integer> ints = new ArrayList<Integer>();
ints.add(100);
ints.add(1);
ints.add(15);
ints.add(42);
ints.add(187);
System.out.println("Original List");
for(Integer i: ints){
System.out.println(i);
}
/* Remove any even elements from the list */
for(int i=0; i < ints.size(); i++){
if(ints.get(i) % 2 == 0){
ints.remove(i);
}
}
System.out.println("\nModified List");
for(Integer i: ints){
System.out.println(i);
}
}
}
Lets assume that you are talking about an input list that is an ArrayList.
The following approach will give you O(N) behaviour (for at least OpenJDK Java 6 through Java 8):
Create a HashSet.
Iterate over the elements of your input list:
Visit the element and add it to the set if it should be removed
Visit the neighbours of the element and add to the set any one that should be removed.
Call list.removeAll(set).
The removeAll method for ArrayList calls an internal batchRemove method (see here). This method performs a single pass over the ArrayList's backing array, removing elements and filling the holes. It tests each element to see if it should be removed by calling set.contains(elem). For a HashSet that test is O(1), and hence the removeAll(set) call is O(N) where N is the list size.
It is interesting to note that arrayList.removeAll(hashSet) will be O(N) where N is the list length, but removing the same elements like this:
for (Iterator it = arrayList.iterator; it.hasNext(); ) {
if (hashSet.contains(it.next())) {
it.remove();
}
}
will be O(NM) where N is the list length and M is the set size.

Confusion regarding the initial position of the pointer in a list iterated by the Iterator interface

where is the initial index of the pointer to the list should it not
be the first item of the list.
does the next method
(1)returns the next element of the and points to the next element
or
(2) return original element and sets the pointer to the next element.
but if (1) is true then the pointer is on the first element then the first element cannot be returned i.e if (1) is true the pointer should be before the first element i.e in
some kind of -1 position.
on the other hand if (2) is true then we can remove the first element but we cannot get the next element by usingthe next because we will reduce the index by 1;
which brings me to the next question does remove() method reduce the index by one or keeps it same??
The contextual code is given below::
package iterators;
import java.util.ArrayList;
import java.util.Iterator;
public class Array_practice {
public static void main(String args[])
{
ArrayList<Integer> list= new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator= list.iterator();
iterator.remove();//does not work why??
}
}
where is the initial index of the pointer to the list should it not be the first item of the list
No. It is before the first item of the list. You only get to the first item when you call next() for the first time.
In fact, it's usually simpler to think of the iterator as between items. So for example, with your list:
1 2 3
^ // Initial position
^ // After calling next()
^ // After calling next()
^ // After calling next() the third time - now hasNext() will return
// false
Then remove() - as documented - removes the item that was last returned.
You're calling remove() before any items have been returned... so there's nothing to remove.
The Javadoc for the Iterator interface is as follows :
void remove()
Removes from the underlying collection the last element returned by this iterator (optional operation). This method can be called only once per call to next(). The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
So using remove() before having ever called next() will never return an element. This of course is if the class you're iterating respects the contract for implementing Iterable - which is obviously the case of ArrayList and other java.util collections.

ArrayList Method: iterator()

I cannot find out what this method does. Can someone please explain?
Example:
for (Iterator ite = list.iterator(); ite.hasNext(); )
Thanks, I just started learning java. Currently grade 9.
It's just "reading" the list with an iterator (useful if you want to remove elements from the list while reading).
You can get an element from the iterator with
Item item = ite.next();
if you want to remove the item from the list you can do simply
ite.remove();
You can loop a list also with simpler for, like
for (Item item : list) {
System.out.println(item.toString());
}
or
for (int i = 0; i<list.size(); i++) {
Item item = list.get(i);
System.out.println(item.toString());
}
but with these, if you try to do list.remove(item) or list.remove(i) you will raise an exception (ConcurrentModificationException if I'm not wrong).
At a very basic level, an iterator "walks through" the list until it gets to the end. So in that method, you're creating an object that points at one object in the list. When you call next() on the iterator, it moves to the next object in the list. And when you call hasNext() on the iterator, you're asking whether the iterator has anywhere else to go, or whether it's at the end of the list. hasNext() will return true if the iterator has a next() and false otherwise.
You likely want to create your for loop like this:
for ( Iterator iter = list.iterator(); iter.hasNext(); iter.next() )
which creates a new iterator for the list (the first element). Each time the loop comes back, it calls iter.next() which makes the iterator point to the next element in the list. When you've gotten to the end of the list, iter.hasNext() is no longer true, and so the loop breaks.
In short, you're just creating a for loop that goes through every element of the list.

Categories

Resources