javaiteratordefault-method

Java 17: MenuIterator is not abstract and does not override abstract method remove() in java.util.Iterator


I'm getting the following error while implementing the java.util.Iterator interface in my class:

java: MenuIterator is not abstract and does not override abstract method remove() in java.util.Iterator.

import java.util.Iterator;

public class MenuIterator implements Iterator<MenuItem> {
    private final MenuItem[] items;
    private int position = 0;

    public MenuIterator(MenuItem[] menuItems) {
        this.items = menuItems;
    }

    public boolean hasNext() {
        return position < items.length && items[position] != null;
    }

    public MenuItem next() {
        return items[position++];
    }
}

remove() method is a default method in the Iterator interface, as well as forEachRemaing() method.

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }

However, I am not forced to implement forEachRemaing(), but I do have to implement remove(). Also, the code works without implementing remove() if I run it from Eclipse, but gives an error in IntelliJ IDEA.

Does anyone know why I would need to provide an implementation for the default remove() method? Why should I provide it for one method and not for another? And why does it work without implementation in one IDE and not in another?


Solution

  • The remove() method in java.util.Iterator has a default implementation now, but it didn't in older versions. Specifically, it gained this in java8 (because java8 introduced default methods - but Iterator's remove is older than that).

    You have configured your intellij that your source code is versioned at 7 or lower, and/or have told intellij to compile and run it all on a JDK at version 7 or below.

    These versions are very very obsolete/unmaintained/outdated; the lowest java version still in common use is java 8; there is very little reason to write libraries such that they run on even that very very low version.

    If you truly want to support that version, you have to write remove() by hand - that same version (java7 or below) did not have a forEachRemaining method at all, hence why you get no errors about it not being in your implementation: Either it wasn't there at all, or it has a default impl. Unlike remove(), which pre-8 was there and had no default (because the feature didn't exist), and post-8 was still there but now with a default.

    Exactly how you've set up your project so that you ended up with something configured at 7 or below is not clear from your question. If you have issues fixing it, you should find a tutorial or ask a separate question from this one.