简体   繁体   English

如何在具有ArrayList的类中实现Iterable

[英]How do I implement Iterable in a class that has an ArrayList

I am going to have a class that has a ArrayList people field I want clients of this class to be able to iterate over those objects. 我将要创建一个具有ArrayList people字段的类,我希望此类的客户端能够迭代这些对象。 How do I do this? 我该怎么做呢? Do I just return people.iterator(); 我是否只返回people.iterator(); ?

for example, in the client I want to be able to do this: 例如,在客户端中,我希望能够做到这一点:

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

Is this what I need in my class? 这是我班上需要的吗?

public class People  implements Iterable<Person> {

private ArrayList<Person> people;

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

If you want to prevent modification to the list itself via the iterator, just delegate iterator() to an unmodifiable list like this: 如果要防止通过迭代器修改列表本身,只需将iterator()委派给不可修改的列表,如下所示:

public class People implements Iterable<Person> {

    private ArrayList<Person> people;

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

}

Otherwise, what you have is fine. 否则,您所拥有的就好了。

Note, however, that unless Person is immutable, there is nothing you can do to prevent a caller from modifying the Person objects themselves. 但是请注意,除非Person是不可变的,否则您无法采取任何措施阻止调用者修改Person对象本身。 If that's OK, then no big deal. 如果可以,那么没什么大不了的。 If that's a problem, then you could create a deep copy of people and return an iterator to that. 如果这是一个问题,那么你可以创建一个深层副本people ,并返回一个迭代了这一点。

If you want the returned iterator to reflect modifications to the Person s but not to allow changing of the Person s, or if a deep copy is too expensive or unnecessary, you could create an ImmutablePerson that extends Person and wraps a Person but does not allow modification via setters, and return a list of those wrapped around the actual Person objects. 如果您希望返回的迭代器反映对Person的修改,但不允许更改Person ,或者如果深拷贝过于昂贵或不必要,则可以创建一个ImmutablePerson来扩展Person并包装一个Person但不允许通过设置器进行修改,并返回包裹在实际Person对象周围的列表。

Yes. 是。 The enhanced for loop requires an array or Iterable . 增强的for循环需要一个数组或Iterable Iterable is required to have iterator( that returns a reasonable iterator that has useful meaning in regard to your data. 需要Iterable拥有iterator(返回一个合理的迭代器,该迭代器对您的数据具有有用的含义。

You can now use the enhanced for loop and it is somewhat semantically correct. 现在,您可以使用增强的for循环,它在语义上有些正确。 However, Iterator provides remove( so anyone using your iterator can remove things from your people list, which may not be what you want. Perhaps using new ArrayList(people).iterator() or Collctions.unmodifiableList(people).iterator() can work as you copy the list and get the iterator for it . 但是, Iterator提供remove(这样,使用迭代器的任何人都可以从您的人员列表中删除内容,这可能不是您想要的。也许可以使用new ArrayList(people).iterator()Collctions.unmodifiableList(people).iterator()可以在复制列表并为其获取迭代器时可以工作

You can also provide getPeople by creating a getter that creates an ImmutableList or just a copy of your internal arrayList. 您还可以通过创建一个创建ImmutableList或仅是内部arrayList副本的getter来提供getPeople

On another note, why not extend ArrayList if you need extra functionality? 另外,如果需要额外的功能,为什么不扩展ArrayList? I haven't seen exactly what you're doing with it so I can only guess. 我还没有完全了解您在做什么,所以我只能猜测。

Simply provide a getter for your People list: 只需为您的人员列表提供一个吸气剂即可:

public ArrayList<Person> get getPeople() {
   return people;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM