This week, we have been learning about how Java has entered the world of functional programming, treating functions as first class citizens. In today's lab, we will implement some of that knowledge.
In class, we used an example of functional programming by describing the map method, which takes an array and a function as an argument, and applies the function to each element of the array to produce a result. Today, we are going to investigate a couple of different methods which take functions as arguments. The first is a method which produces a sequence of numbers, where the function describes how to get the next element of the sequence. We will look at several variations of sequence generators. We will also investigate a reduce method, which collapses an array into a single result by applying a function to each element of the array.
Create a lab10 package, and create a class called XmpFunc. This class does not need a constructor or any fields, we are using it as a container to hold our static methods. We will make several methods, as follows:
This method takes three arguments; an initial value, a function that takes a Double value as an argument, and returns a Double value as a result, and an integer count. This function should create an array of doubles that has count elements, and put the initial value in the first element. Then for the remaining elements in the array, determine the value of the next element by applying the fn function to the previous element. Return the complete array, once you have filled in all count elements. Refer to Lecture 17 Slide 30 for an example of how to do this.
Before continuing, let's test this method. In the main method, invoke the sequence method with arguments 1.0, a lambda expression which adds 1 to its argument, and the number 10. Use the Arrays.toString method to print the result. Try various different values for the initial value, the function argument, and the count to see what happens. For instance, what if you add 2 instead of 1, or multiply by 2 and add 1? What happens if you take the reciprocal of the argument? What about 1/(1+x)?
Code this method, and add some invocations of the method in your main function. For instance, if you just add the index to the previous member, you get a sequence of 2n - 1. If you multiply the index by the previous value, you get a sequence of factorials.
Try the reduce function with simple addition to find the sum of an array. Try with multiplication to find the product. Try some other alternatives as well.
It can be argued that an indexSequence can be used to generate a simple sequence because indexSequences are just generalized forms of sequences. Can you code an invocation of indexSequence that produces an array with the numbers [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]? (There are many many ways to do this.)
The Fibonacci sequence is a famous sequence of numbers where each element is the sum of the previous two elements. Can you code a method called biSequence that takes two initial values as arguments, along with a BiFunction and a count, and applies the function to the previous two values to get the next value? Then if you invoke this with biSequence(1,1,(x,y)->(x+y),10), you will get the first ten elements of the Fibonacci sequence.
Can you write a one-line instruction in your main code to calculate the sum of the first 10 elements in the Fibonacci sequence? (I came up with 143.)
Zip your code in the lab10 package, and submit it on myCourses. This lab is worth 10 points. You will get the full 10 points if your code compiles without warnings, and produces the correct output. The CA's have their own "main" function that invokes your methods with some pre-defined arguments. The following are reasons for deductions: