Question

I'm having trouble understanding a method. I have methods that I need to fill out, but I don't really understand the first one. How can Iterable be a return type and how is it used ? An example would be great..

@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!
}
Was it helpful?

Solution

It looks like your class should have an implementation of Iterable<ClientInterface> as a class member, like ArrayList.

Let's use this as an example:

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

   public Iterable<Person> getRiders() {

     return riders;

   }
   ... //other methods
}

OTHER TIPS

Everything can be a return type: an enum, a class, an interface, an int, an exception etc.

Iterable is an interface which could be used to use the return in a foreach call (that's why you can use for(T something : AnArrayList) because ArrayList<T> implements Iterable<T>)

Now, my answer contains an example:

We have a method getNeighbours which returns Iterable<ClientInterface>

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

Well, ok since Iterable is just an interface we need to implement methods or use an implementation.

Since it's something which we should do manually we should implement the methods by ourself.

The only method (in Java8, there are 3 methods but we will ignore it) is iterator() which returns an iterator.

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

Iterator is another interface which is used to provide the logic to iterate over the collection, a list of items etc.

We are forced to implements two methods: hasNext and next

hasNext is used to determinate if there are more items to iterate over, next is used to iterate over it.

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;
                }
            };
        }
    };
}

We here need to remember which was our last position so we would create a field inside our Iterator.

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;
                }
            };
        }
    };
}

Here the problem: What we should iterate? It depends to you, an example could be:

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++];
                }
            };
        }
    };
}

Note here how we created an array of items and used our two methods hasNext and next to provide a way to iterate over it.

Every call of next increment the internal pointer, and our hasNext method just checks if the pointer reached the end of the array.

Collections like ArrayList, LinkedList etc. already did the job for you and better (implements remove method) you can get this iterator by using ArrayList.iterator()

Now you could write something like:

for (ClientInterface el : yourClass.getNeighbours())
{
    System.out.println(el);
}

Iterable<T> is an interface. What this means is that when you receive it as a return value from a method, you actually receive an implementation of it. So, although you don't know what the name of that implementation is (the name of the class that implements the Iterable<T> interface), you can still access the methods that it implements, and act upon it.

Some built-in implementations include ArrayList, LinkedList, HashSet, PriorityQueue, and Stack.

When you need to return an interface type, you must return an implementation of it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top