可迭代对象作为返回类型

7
我有困难理解一种方法。我需要填写一些方法,但我不太理解第一个。Iterable如何成为返回类型以及如何使用?提供一个例子会很好。
@Override
public Iterable<ClientInterface> getNeighbours() {

    return null;
}

@Override
public void addNeighbour(ClientInterface newNeighbour){
    //TODO Implement me!
}

@Override
public void removeNeighbour(String clientID) {
    //TODO Implement me!
}

2
尝试将一个列表作为私有成员添加到你的类中,并在这三个方法中使用它。 - Dan W
1
https://dev59.com/8G025IYBdhLWcg3wtoM_ - AntonH
2
你为什么认为Iterable不能作为返回类型呢?当然可以。 - Boann
3个回答

9

看起来您的类应该有一个Iterable<ClientInterface>的实现作为类成员,就像ArrayList一样。

我们以此为例:

public class Bus {
   private ArrayList<Person> riders;
   ... //constructors and other methods

   public Iterable<Person> getRiders() {

     return riders;

   }
   ... //other methods
}

8

一切都可以是返回类型:枚举,类,接口,int,异常等。

Iterable是一个接口,可用于在foreach调用中使用返回值(这就是为什么您可以使用for(T something : AnArrayList),因为ArrayList<T>实现了Iterable<T>

现在,我的回答包含一个示例:

我们有一个方法getNeighbours,它返回Iterable<ClientInterface>

public Iterable<ClientInterface> getNeighbours()
{
    return new Iterable<ClientInterface>();
}

好的,既然Iterable只是一个接口,我们需要实现方法或使用一个实现。

既然这是需要我们手动完成的事情,我们应该自己实现这些方法。

在Java8中,唯一的方法(虽然有3个方法,但我们将忽略它们)是iterator(),它返回一个iterator

public Iterable<ClientInterface> getNeighbours()
{
    return new Iterable<ClientInterface>()
    {
        @Override
        public Iterator<ClientInterface> iterator()
        {
            return null;
        }
    };
}

Iterator是另一个接口,用于提供迭代集合、项列表等的逻辑。

我们被迫实现两个方法:hasNextnext

hasNext 用于确定是否还有更多项可迭代,next 用于进行迭代。

public Iterable<ClientInterface> getNeighbours()
{
    return new Iterable<ClientInterface>()
    {
        @Override
        public Iterator<ClientInterface> iterator()
        {
            return new Iterator<ClientInterface>()
            {
                @Override
                public boolean hasNext()
                {
                    return false;
                }

                @Override
                public ClientInterface next()
                {
                    return null;
                }
            };
        }
    };
}

我们需要记住最后的位置,因此在迭代器中创建一个字段。

public Iterable<ClientInterface> getNeighbours()
{
    return new Iterable<ClientInterface>()
    {
        @Override
        public Iterator<ClientInterface> iterator()
        {
            return new Iterator<ClientInterface>()
            {
                private int position;

                @Override
                public boolean hasNext()
                {
                    return false;
                }

                @Override
                public ClientInterface next()
                {
                    return null;
                }
            };
        }
    };
}

这里的问题是:我们应该迭代什么?这取决于您,一个例子可能是:

public Iterable<ClientInterface> getNeighbours()
{
    return new Iterable<ClientInterface>()
    {
        @Override
        public Iterator<ClientInterface> iterator()
        {
            return new Iterator<ClientInterface>()
            {
                private int position;
                private ClientInterface[] items = new ClientInterface[]{new ClientInterface(), new ClientInterface()};

                @Override
                public boolean hasNext()
                {
                    return position != items.length;
                }

                @Override
                public ClientInterface next()
                {
                    if (!hasNext()) throw new NoSuchElementException();
                    return items[position++];
                }
            };
        }
    };
}

请注意这里我们创建了一个项目数组,并使用hasNextnext两种方法提供一种遍历它的方式。
每次调用next都会增加内部指针,而我们的hasNext方法只是检查指针是否到达了数组的末尾。
ArrayListLinkedList等这样的集合已经为您完成了工作,并且更好(实现了remove方法),您可以使用ArrayList.iterator()来获取此迭代器。
现在,您可以写出如下内容:
for (ClientInterface el : yourClass.getNeighbours())
{
    System.out.println(el);
}

感谢您的出色解释!private ClientInterface[] items = new ClientInterface[]{new ClientInterface(), new ClientInterface()};如何从接口创建对象?如果我想添加更多ClientInterface,会发生什么? - tlq
在这种情况下,您不创建接口,而是创建一个实现接口的匿名类(请注意{})。在这种情况下,这只是一个示例,无论如何,您的数据应该在外部类中而不是迭代器中,否则每次都会创建一个副本。 - Marco Acierno

3

Iterable<T>是一个接口。这意味着当你从一个方法中作为返回值获得它时,你实际上获得的是它的一个实现。因此,尽管你不知道该实现的名称(实现了Iterable<T>接口的类的名称),但你仍然可以访问它所实现的方法并对其进行操作。

一些内置的实现包括ArrayListLinkedListHashSetPriorityQueueStack

当你需要返回一个接口类型时,你必须返回它的一个实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接