Почему я получаю ошибку компилятора foreach, хотя Iterable реализован? - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь изучить различные шаблоны проектирования в ООП, и текущий, который я изучаю, является шаблоном итератора.Поэтому я сделал два собственных интерфейса (Iterable и Iterator).

Я пытаюсь перебрать List<Person> friends.Но строка: for (Person p : p1) выдает следующую ошибку компилятора:

foreach not applicable to type 'com.company.Person'

Что для меня не имеет смысла, так как я реализовал Iterable и переопределил метод iterator (), насколько я вижу.

Может кто-нибудь сказать мне, что мне не хватает?

Вот мой код:

Основной класс:

Person p1 = new Person("Erik");
    p1.addFriend("Lars");
    p1.addFriend("Jenny");
    p1.addFriend("Janne");


    for (Person p : p1) {
        System.out.println(p.name);
    }

Итератор:

public interface Iterator<T> {

    boolean hasNext();

    T next();

    void remove();
}

Итерируемый:

public interface Iterable<T> {
    Iterator<T> iterator();
}

Человек:

public class Person implements Iterable<Person>{
    private List<Person> friends = new ArrayList<>();
    String name;
    int index = 0;
    public Person(String name){
        this.name = name;
    }

    public void addFriend(String name){
        friends.add(new Person(name));
    }

    @Override
    public Iterator<Person> iterator(){
        return new Iterator<Person>() {
            //int index = 0;
            @Override
            public boolean hasNext() {
                System.out.println(index);
                return index < friends.size();

            }    

            @Override
            public Person next() {
                if(hasNext()){
                    return friends.get(index++);
                }
                else{
                    return null;
                }
            }
            @Override
            public void remove() {
                if(index<=0) {
                    friends.remove(index--);
                }
            }
        };
    }
}

1 Ответ

0 голосов
/ 21 декабря 2018

Похоже, вы определили свои собственные интерфейсы Iterator и Iterable.Это не то, как цикл foreach работает в Java.

Чтобы класс был жизнеспособной целью для цикла foreach, он должен реализовывать встроенный Iterable, видимый в java.lang.Iterable.Удалите свои собственные интерфейсы Iterator и Iterable и внедрите встроенный Iterable (а также используйте встроенный Iterator).

Кроме того, насколько семантика идет,Возможно, не имеет смысла иметь класс Person равным Iterable.Коллекция друзей этого человека должна быть Iterable.Вместо этого вы можете захотеть раскрыть коллекцию друзей с помощью метода getFriends(), который вернет неизменяемое представление этого списка (Collections.unmodifiableList(friends)).Список уже Iterable, избавляя вас от необходимости реализовывать его в первую очередь.

...