L.1 A functor is an object that encapsulates a function. Its apply() method take
ID: 3702489 • Letter: L
Question
L.1
A functor is an object that encapsulates a function. Its apply() method takes one parameter,
applies an algorithm and returns a value. It is defined as a 'functional' interface:
interface Functor<R,T> {
// apply(p) runs some computation on param of type T and returns a value of type R
public R apply(T param);
}
a) Write a class implementing the Functor<Integer,String> interface, called LengthFun.
Its apply() function returns the length (Integer) of a String parameter.
Write a LengthFun.main() function that:
o illustrates how the class is used to print the length of a string.
o instantiates a lambda expression of type Functor<Integer, String> that does the same
thing as LengthFun.apply(), and uses it to print the length of a string.
b) Define a subclass of LinkedList<E>, called MyList<E>, that has an additional
generic function that "maps" the elements from the list to a new MyList<E> object through a functor object.
The signature of the MyList<T>.map() method is:
public <R> MyList<R> map(Functor<R,T> fo) {
// write here the code for the map() function.
}
For an object mylist the mylist.map(fo) creates a new MyList<R> object,
iterates over the elements of mylist and appends values fo.apply(current list element)
to the new list. At the end map() returns the new list.
For instance, consider a TimesTwoFun<Integer,Integer> functor whose
Integer apply(Integer param)
function returns 2*param.intValue(). Define a variable tt = new TimesTwoFun();
Now, suppose the elements of a MyList<Integer> object lst are (-2,1,0,4). Then ,
the new MyList<Integer> object returned by the lst.map(tt) will have elements (-4,2,0,8).
That is, the lst.map(fo) function creates a new MyList object with elements equal to fo.apply(x),
for each element x from the lst list.
Write the TimesTwoFun<Integer> class.
Write the MyList<T> class that extends LinkedList<T>, with the only custom method being map()
(all others are inherited from LinkedList<T>).
Write a main() function in MyList.java that:
o implements the example defined above with the TimesTwoFun class.
o repeats the same thing using a lambda expression insted of the TimesTwoFun object.
c) A Functor2<R,T1,T2> interface describes a function
with 2 variables of types T1, and T2, respectively, and returning a value of type R.
The apply function takes one parameter of type T1, one parameter of type T2, and returns
type R.
interface Functor2<R,T1,T2> {
R apply(T1 param1, T2 param2);
}
Add a reduce() function to the MyList<T> class that takes as parameters a Functor2 object,
and an initial value of type T.
public <R, T2> R reduce(Functor2<R,T,T2> fo2, T2 initialValue) {
// write code here
}
reduce(fo2, initVal) returns the sucessive "cummulative" application of
the Functor2 apply() function to all elements of the list, beginning with the initial value and
the first element of the list.
For instance, assume the list elements are (a,b,c,d) and that a Functor2 object fo2 is defined.
Then the reduce(fo2, v) call returns
fo2.apply(fo2.apply(fo2.apply(fo2.apply(v, a), b), c), d)
As a second example, a class called Summer implements the Functor2<Integer, Integer, Integer> interface.
Summer.apply(x,y) returns x + y. Declare the summer ref. variable to be a reference to a Summer object.
Assume the elements in the list are (3, -1, 1, 4). Then lst.reduce(summer, 0) should return
((((3+0)+(-1))+1)+4) == 7, i.e. the sum of all elements in the list.
To do:
o Write the generic reduce() function in the MyList<T> class defined first at point b).
Make sure the function's parameter/return types are defined correctly.
o Write the Summer class that implements the Functor2<Integer,Integer,Integer>
interface, as described above.
o Write a test driver class called SummerTest with a main() function that:
i) implements the example above with the Summer object and the list with numbers.
ii) implements the example above with a lambda expression instead of a Summer object.
Make sure the code works.
d) The map and reduce functions are part of the functional programming paradigm
and are widely used in non-functional languages as well.
To understand the power of the map/reduce combination, use the code written in parts a)-c))
to implement the following in a the main() function of class MRExample:
- create a MyList<String> object ls with several nonempty String objects added to it
- use function ls.map() to return the list of Integer objects representing the length of each string
in ls. Use the LengthFun functor class. Call the returned list a variable li.
- Use li.reduce() with a Summer object to compute the total number of characters in all strings in the
ls list.
e) Write in the main() function of a new class MRExampleWithLambdas the same logic as in part d)
***using lambda expressions*** and chain the map() and reduce() calls in one expression:
ls.map(...).reduce(....).
Explanation / Answer
Java program:
import java.util.LinkedList;
public class MyList<T> extends LinkedList<T>
{ // starting of the function
public static void main(String[] args)
{// starting of anothyerr function
Summer summer = new Summer();
MyList<Integer> l = new MyList<>();
l.add(3);
l.add(-1);
l.add(1);
l.add(4);
Integer result = l.reduce(summer,0);
System.out.println(result);
} ending of the function
public <T, R extends Functor> MyList<T> map (R element)
{
MyList<T> newList = new MyList();
for(int i = 0; i < this.size(); i++)
{
T applied = (T) element.apply(this.get(i));
newList.add(applied);
}
return newList;
}
public <T, R extends Functor2> T reduce(Functor2 element, T initialValue)
{
T temp;
temp = (T) element.apply(this.get(0), initialValue);
for(int i = 1; i<this.size(); i++)
{
temp = (T) element.apply(this.get(i), temp);
}
return temp;
}
}
**
public class SummerTest
{
public static void main(String[] args)
{
Summer summer = new Summer();
MyList<Integer> l = new MyList<>();
l.add(3);
l.add(-1);
l.add(1);
l.add(4);
Integer result = l.reduce(summer,0);
System.out.println(result);
}
}
**
public interface Functor<R,T>
{
R apply(T param);
}
**
public class TimesTwoFun implements Functor <Integer, Integer>
{
@Override
public Integer apply(Integer param)
{
return param * 2;
}
}
**
public class Summer implements Functor2<Integer, Integer, Integer>
{
@Override
public Integer apply(Integer param1, Integer param2)
{
return param1 + param2;
}
}
**
public class LengthFun implements Functor<Integer,String>
{
@Override
public Integer apply(String param)
{
return param.length();
}
public static void main(String[] args)
{
LengthFun fun = new LengthFun();
System.out.println(fun.apply("Hello"));
}
}
**
public interface Functor2 <R,T1,T2>
{
R apply(T1 param1, T2 param2);
}
**
import java.util.LinkedList;
public class Main
{
public static void main(String[] args)
{
MyList<String> ls = new MyList();
ls.add("one");
ls.add("two");
ls.add("three");
LengthFun length = new LengthFun();
MyList newList = ls.map(length);
System.out.println("lengh of first value: " + newList.get(0));
Summer s = new Summer();
int result = (int) newList.reduce(s, 0);
System.out.println("Total value:" + result);
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.