سؤال

Implement an iterator(Generic) which skips next element if it is equal to last printed element. e.g : AAABBCCCCD On complete iteration will print ABCD.

Below is my attempt. Please suggest if it can be done in a better way.

import java.util.Iterator;

public class DeDupIterator<E> implements Iterator<E> {

E next = null;
Iterator<E> itr;

public DeDupIterator(Iterator<E> iter) {
    itr = iter;
    next = itr.next();
}

@Override
public boolean hasNext() {
    if(itr.hasNext())
    if (next != null) {
        return true;
    }
    return false;
}

@Override
public E next() {
    E item=null;
    while (itr.hasNext()) {
        item = (E) itr.next();
        if (!item.equals(next)) {
            E temp = next;
            next = item;
            return temp;
        }

    }
    next = item;
    return next;

    }

    @Override
    public void remove() {
        itr.remove();
    }
}
هل كانت مفيدة؟

المحلول

It's hard to answer this question without actually writing the code for you.

I'll just focus on main issues with this code:

  • it doesn't work for empty collections, because it calls itr.next() unconditionally in the constructor, which leads to an exception
  • it doesn't work for a single element collections, because hasNext() returns false instead of true - this is because you call itr.next() in the constructor and then in hasNext() you first check itr.hasNext()
  • remove() is completely wrong, because itr.next() was called earlier
  • it should throw NoSuchElementException in next() if there is no element to return, but it doesn't

How to fix it?

I would start by removing itr.next() from constructor as it's messing many things up.

Then you have to somehow distinguish between two cases: when itr.next() was called in advance or not. E.g. add a boolean field to facilitate that.

You will have to call itr.next() in advance if hasNext() is called.

Also you should be prepared that itr.next() returns null as a completely valid value that can be stored in a collection. You should not rely on next to be not null. For this reason you should have one more boolean that determines whether your next field actually holds a value or is empty.

The remove() method should probably remove all the duplicates and not only one element. If you find it too demanding to implement you can always throw UnsupportedOperationException. If you decide to implement it, remember to throw IllegalStateException if next() has not yet been called, or remove() has already been called after the last next() call

This should be enough for you to get the right solution yourself. Good luck.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top