Sieve of Eratosthenes in Java

Your task: Redo the "Sieve of Eratosthenes" problem that we did in Scheme, using lazy lists, in Java. Since Java does not support first-class functions, we'll fake it. We will use an interface to contain a function:

interface Function
{
  LazyList f();
}

All implementations of Function will simply override f to be a particular function. For example, here is an excerpt from the infSeq function that you will write:

class LazyList
{
  ...
  public static LazyList infSeq(final Integer start)
  { 

    class InfSeqTail implements Function
    {
      public LazyList f()
      {
        return infSeq(start+1);
      }
    } // end of inner-class definition

    return new LazyList(start, new InfSeqTail());
  }
  ...
}

Whenever a particular function must be passed as a value, an instance of an implementation of Function is used.

The class you need to build, LazyList, is structured as:

class LazyList
{
  private Integer head;      // Head of this list, null if list is empty
  private Function tail;     // Function to compute tail of this list
                             // (if head is not null)
  public LazyList()          // Default constructor for LazyList
  {
    head = null;
    tail = null;
  }
  public LazyList(Integer head, Function tail)
  {
    // Another constructor
    this.head = head;
    this.tail = tail;
  }
  public static LazyList seq(final Integer start, final Integer finish)
  {
    // Same definition as in previous assignment
  }
  public static LazyList infSeq(final Integer start)
  {
    // Same definition as in previous assignment
  }
  public Integer nth(int n)
  {
    // Same definition as in previous assignment
    // EXCEPT that it returns null if if n-th element does not exist
  }
  public void printN(int n)
  {
    // Like firstN except that values are printed
    // rather than formed into a list.
  }
  public static LazyList filterMultiples(final Integer factor,
                                         final LazyList data)
  {
    // Same definition as in previous assignment
  }
  public static LazyList primes()
  {
    // Same definition as in previous assignment
  }

  public static void main(String[] args)
  {
    // Create a lazy list and test that it works
    LazyList primes = LazyList.primes();
    primes.printN(15);
    System.out.println(primes.nth(20));
  }

}

You could accomplish the same behavior in a slightly more confusing but considerably more condensed format using anonymous inner classes. After you get your code working, create another class called LazyListAnon that redoes all of the above with anonymous inner classes.


Submit your code in files called LazyList.java and LazyListAnon.java.