einpoklum
einpoklum

Reputation: 131515

How can I generate a List backed by a Function?

I have a function myFunction of Function<Integer, T>, and I want to construct an object mylist of size size, implementing List<T> (or maybe some kind of immutable list interface), backed by the function, in the sense that mylist.get(i) == myFunction.apply(i).

I can do this manually, but is there some (Guava) code which does the same?

Upvotes: 2

Views: 162

Answers (2)

OldCurmudgeon
OldCurmudgeon

Reputation: 65803

Perhaps instead of a list you should consider an Iterator<T>.

// Example simple Function that returns each element from the array.
static class Function<T> {
    final T[] t;
    Function(T[] t) {
        this.t = t;
    }
    T apply (Integer i) {
        return t[i];
    }
}

static class FunctionIterator<T> implements Iterator<T> {
    final Function<T> f;
    Integer i;
    Integer to;
    Integer step;

    FunctionIterator(Function<T> f, Integer from, Integer to) {
        this.f = f;
        if ( to > from ) {
            step = 1;
            i = from;
            this.to = to;
        } else {
            step = -1;
            i = to;
            this.to = from;
        }
    }

    @Override
    public boolean hasNext() {
        return i != to + step;
    }

    @Override
    public T next() {
        T next = f.apply(i);
        i += step;
        return next;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }
}

This code offers an Iterator. You can make an Iterable from it quite easily. Here is an excellent and neat example of how to do it.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198023

Just use java.util.AbstractList:

 new AbstractList<T>() {
   public T get(int i) {
     Preconditions.checkElementIndex(i, size);
     return function.apply(i);
   }
   public int size() {
     return size;
   }
 }

The result would not necessarily be immutable, since the function output could vary. In all likelihood, you could get rid of the Function entirely, and just write the implementation of the Function in your AbstractList implementation.

Upvotes: 5

Related Questions