【问题标题】:Why do I get a foreach compiler error even though Iterable is implemented?为什么即使实现了 Iterable,我也会收到 foreach 编译器错误?
【发布时间】:2023-03-29 03:49:01
【问题描述】:

我正在尝试在 OOP 中学习不同的设计模式,而我目前正在学习的是迭代器模式。因此我制作了两个自己的接口(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--);
                }
            }
        };
    }
}

【问题讨论】:

  • 好像您创建了自己的Iterable&lt;...&gt; 界面? foreach 仅适用于java.lang.Iterable
  • 另外,Person 是不可迭代的。 Person集合是。如果您已经拥有Person 的集合(就像您所做的那样),那么您应该已经能够迭代该集合。
  • 换句话说,它应该是for (Person p : friends) { // do something with p },读作“对于你的friends集合中的每个Person p,用p做一些事情”

标签: java design-patterns foreach iterator iterable


【解决方案1】:

看起来您已经定义了自己的IteratorIterable 接口。这不是 foreach 循环在 Java 中的工作方式。

要使一个类成为 foreach 循环的可行目标,它必须实现内置的 Iterable,参见 java.lang.Iterable。移除你自己的IteratorIterable接口,实现内置的Iterable(同时使用内置的Iterator)。

此外,就您的语义而言,将Person 类设为Iterable 可能没有多大意义。该人的朋友的收藏应该是Iterable。相反,您可能希望通过 getFriends() 方法公开朋友的集合,该方法将返回该列表的不可修改视图 (Collections.unmodifiableList(friends))。该列表已经是Iterable,让您无需首先实现它。

【讨论】:

  • 是的,我想我记得我的老师是这样做的,这就是为什么我专门尝试实现我自己的书面界面。再次仔细检查了他的讲座后,似乎他确实使用了现有的界面。我认为他出于某种教育目的开设了自己的课程,然后又回到了现有的课程中。关于获取 unmodifiableList 的智能提示。我会记住的。这个例子只需要一个实现 Iterable 的类来测试它是如何工作的。
猜你喜欢
  • 2018-05-24
  • 2019-10-11
  • 2022-11-03
  • 2012-03-13
  • 2022-06-12
  • 2020-10-25
  • 1970-01-01
  • 2021-06-29
相关资源
最近更新 更多