140 likes | 242 Views
Computer Science 209. The Strategy Pattern II: Emulating Higher-Order Functions. Higher-Order Functions. In functional or procedural languages, a higher-order function allows clients to apply a function parameter to a list of values and receive a list of results
E N D
Computer Science 209 The Strategy Pattern II: Emulating Higher-Order Functions
Higher-Order Functions • In functional or procedural languages, a higher-order function allows clients to apply a function parameter to a list of values and receive a list of results • map: transform the values • filter: retain the values that pass a test • reduce: boil or fold the values down to a single value
Examples of HOFs in Python >>> list(map(math.sqrt, [2, 4, 6])) [1.4142135623730951, 2.0, 2.449489742783178] >>> list(filter(lambda n: n % 2 == 0, range(1, 11))) [2, 4, 6, 8, 10] >>> functools.reduce(lambda x, y: x * y, range(1, 101), 1) 9332621544394415268169923885626670049071596826438162146859 2963895217599993229915608941463976156518286253697920827223 758251185210916864000000000000000000000000 Strategy pattern with functions!
Map/Filter/Reduce in Java • Java has no functions, only methods • Think of an HOF as a static method, with a collection argument and an object argument that implements a particular kind of strategy • Define a strategy interface for each type of HOF • Should work with any iterable collection
New Resources • In the package functools: • The class HOF, with the static methods map, filter, and reduce • The interfaces MapStrategy, FilterStrategy, and ReduceStrategy
Using the New Resource: Mapping import functools.HOF; import functools.MapStrategy; MapStrategy<Integer, Double> sqrt = new MapStrategy<Integer, Double>(){ public Double transform(Integer i){ return Math.sqrt(i); } }; List<Integer> list = new ArrayList<Integer>(); List<Double> results = HOF.map(sqrt, list); Obtain the square roots of a bunch of integers
Using the New Resource: Filtering import functools.HOF; import functools.FilterStrategy; FilterStrategy<Integer> even = new FilterStrategy<Integer>(){ public boolean accept(Integer i){ return i % 2 == 0; } }; List<Integer> list = new ArrayList<Integer>(); List<Integer> results = HOF.filter(even, list); Obtain the even numbers
Using the New Resource: Folding import functools.HOF; import functools.ReduceStrategy; ReduceStrategy<Integer> multiply = new ReduceStrategy<Integer>(){ public Integer combine(Integer i, Integer j){ return i * j; } }; List<Integer> list = new ArrayList<Integer>(); int product = HOF.reduce(multiply, list, 1); Obtain the product of the numbers
The MapStrategy Interface package functools; public interface MapStrategy<E, R>{ /** * Transforms an element of type E * into a result of type R */ public R transform(E element); }
The FilterStrategy Interface package functools; public interface FilterStrategy<E>{ /** * Returns true if element is accepted or * false otherwise */ public boolean accept(E element); }
The ReduceStrategy Interface package functools; public interface ReduceStrategy<E>{ /** * Combines the elements of type E into * a result of type E */ public E combine(E first, E second); }
The HOF Class package functools; public class HOF{ public static<E, R> Collection<R> map( MapStrategy<E, R> strategy, Collection<E> col){ // Implementation is an exercise } public static<E> Collection<E> filter( FilterStrategy<E> strategy, Collection<E> col){ // Implementation is an exercise } … Implementation uses a for loop, etc.
The HOF Class package functools; public class HOF{ … public static<E> E reduce(ReduceStrategy<E> strategy, Collection<E> col, E baseValue){ // Implementation is an exercise } } Implementation uses a for loop, etc.