1

我将有一个具有 ArrayList people 字段的类,我希望此类的客户能够迭代这些对象。我该怎么做呢?我只是返回 people.iterator(); ?

例如,在客户端我希望能够做到这一点:

for( Person p : people ) {
    // do something
}

这是我在课堂上需要的吗?

public class People  implements Iterable<Person> {

private ArrayList<Person> people;

@Override
public Iterator<Person> iterator() {
    // TODO Auto-generated method stub
    return people.iterator();
}
4

3 回答 3

2

如果您想防止通过迭代器修改列表本身,只需委托iterator()给一个不可修改的列表,如下所示:

public class People implements Iterable<Person> {

    private ArrayList<Person> people;

    @Override
    public Iterator<Person> iterator() {
        return Collections.unmodifiableList(people).iterator();
    }

}

否则,你所拥有的一切都很好。

但是请注意,除非Person是不可变的,否则您无法阻止调用者修改Person对象本身。如果没问题,那就没什么大不了的。如果这是一个问题,那么您可以创建一个深层副本people并返回一个迭代器。

如果您希望返回的迭代器反映对Persons 的修改但不允许更改Persons,或者如果深层副本过于昂贵或不必要,您可以创建一个ImmutablePerson扩展Person并包装 aPerson但不允许通过 setter 进行修改的迭代器,并且返回包裹在实际Person对象周围的列表。

于 2013-08-15T01:23:42.407 回答
1

是的。增强的 for 循环需要一个数组或Iterable. Iterable需要iterator(返回一个合理的迭代器,该迭代器对您的数据具有有用的意义。

您现在可以使用增强的 for 循环,它在语义上有些正确。但是,Iterator提供了remove(任何使用您的迭代器的人都可以从您的人员列表中删除的东西,这可能不是您想要的。当您复制列表并获取它的迭代器时,也许使用new ArrayList(people).iterator()or可以工作。Collctions.unmodifiableList(people).iterator()

您还可以getPeople通过创建创建ImmutableList内部 arrayList 的副本或仅创建内部 arrayList 的 getter 来提供。

另一方面,如果您需要额外的功能,为什么不扩展 ArrayList 呢?我还没有确切地看到你在做什么,所以我只能猜测。

于 2013-08-15T01:10:05.843 回答
0

只需为您的人员列表提供一个吸气剂:

public ArrayList<Person> get getPeople() {
   return people;
}
于 2013-08-15T01:10:29.397 回答