Home > Mobile >  can I have an iterator without hasNext()? - Q from school project
can I have an iterator without hasNext()? - Q from school project

Time:01-07

I've got a task to program an iterator that brings back the next letter in the ABC:

if my string is a -> b

if it's ad -> ae

if it's Z -> aa

if it's az -> aA

if it's aZ -> ba

if it's ZZ -> aaa

and so...

I just can't understand what should be in my hasNext(). The teacher told us they won't check us with great numbers of letters so <Max Vaule is unnecessary.

the only thing I can think of is not using this at all but I don't know if I should or how to write that I'm not using it.

CodePudding user response:

I think you are trying to make your own implementation of the Iterator of java.util interface. If you are willing to do so, the hasNext() method should return always true, because there will be always an next element because the Iterator is infinite. Read the JavaDocs of hasNext():

Returns true if the iteration has more elements. (In other words, returns true if next() would return an element rather than throwing an exception.) https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

Code example:

@Override
public boolean hasNext() {
    return true;
}

CodePudding user response:

When we talk about an iterator, we are talking about Iterator class' implementation. This implementation must contain two methods: hasNext() and next().

According to the specification, hasNext() should retrieve true only if next() will retrieve a result. In other words, if hasNext() retrieves false, then there are no more items in the iterator.

public static void main(String... args) {
    Iterator<String> it = new SequenceIterator(2);

    while (it.hasNext())
        System.out.println(it.next());
}

public static final class SequenceIterator implements Iterator<String> {

    private final char[] arr;

    public SequenceIterator(int maxLength) {
        arr = new char[maxLength];
    }

    @Override
    public boolean hasNext() {
        for (char ch : arr)
            if (ch != 'Z')
                return true;
        return false;
    }

    @Override
    public String next() {
        if (!hasNext())
            throw new NoSuchElementException();

        inc(arr.length - 1);

        return new String(arr).trim();
    }

    private boolean inc(int i) {
        boolean res = true;

        if (i < 0)
            res = false;
        else if (arr[i] == '\0')
            arr[i] = 'a';
        else if ((arr[i] >= 'a' && arr[i] < 'z') || (arr[i] >= 'A' && arr[i] < 'Z'))
            arr[i]  ;
        else if (arr[i] == 'z')
            arr[i] = 'A';
        else if (res = inc(i - 1))
            arr[i] = 'a';

        return res;
    }

}

CodePudding user response:

Here is my take based on the information provided. The hasNext() returns a false indicating that you are done, or true if you should continue. So you should return true until you reach the value (or it gets changed) and then return false. The last returned value is the one you want to use. If you don't return false eventually, you will never finish if you keep calling hasNext(), waiting for completion.

In this case, it seems hasNext() will always be called twice since it only takes one change to alter the sequence.

Now, if you are to continue changing the last letter from a given initial value (which wasn't clear in your question), then you should return true.

But what do you do if you keep on returning true and hit AZ? What is the next letter? Do you wrap around and return BA and keep iterating? What about ZZ? Would that then be AAA? Perhaps when you run out of letters (e.g. reach a Z) you should return false next time thru. Only you can answer that based on your intimate understanding of your assignment.

One final thought. If hasNext() always returns true, there is no reason to call it. Everthing required can be handled within next() or some other method. Therefore, one would not even need an iterator implementation.

  •  Tags:  
  • Related