Skip to content

Latest commit

 

History

History
executable file
·
34 lines (19 loc) · 3.67 KB

888a.md

File metadata and controls

executable file
·
34 lines (19 loc) · 3.67 KB

Back to questions

888a: Generic methods with streams

The purpose of this question is to give you practice writing some static methods that use one or more generic parameters, and that also use streams.

  1. Immutable pair. Write a generic class, ImmutablePair, with two generic parameters, S and T say, that allows the construction of an (S, T) pair, and retrieval of its first and second components. Override toString() so that a pair is represented as a string of the form (string representation of first element, string representation of second element).

  2. Placeholder class. Create a class, Example, to serve as a placeholder for the static methods you will write.

  3. Generic list concatenation Recall the concatenate function from question 68e6, which had the signature:

    static List<Integer> concatenate(List<List<Integer>> lists);
    

    and returned the concatenation of the lists in lists. Observe that there is nothing Integer-specific about the notion of concatenating lists.

    Write a version of concatenate that is generic with respect to some type T, and which takes a list of lists of type List<List<T>>, and returns a List<T> that is the concatenation of these lists.

  4. Zip lists of different lengths Write a static method, zip, that is generic with respect to two parameters, S and T, and that takes two parameters, a list first of type List<S> and a list second of type List<T>. The method should return a list of type List<ImmutablePair<Optional<S>, Optional<T>>>. At each index i less than the minimum size of first and second, the result should have a pair of present optionals corresponding to the elements at indices i of first and second. At each index j (if any) at least the minimum size of first and second and less than the maximum size of first and second, the result should have a pair consisting of one present optional and one empty optional; the present optional should be the value at index j of the input list, which must exist.

The zip function is not a good fit for using streams, so feel free to use a loop-based solution. If you are interested in playing more with streams, then consider using the IntStream.range() method to get a stream of integers as long as the maximum size of the two lists, and then use mapToObj to map each integer to the appropriate pair, by getting list elements when they are needed.

  1. Flattening pairs of optionals Write a static method, flatten, that is generic with respect to two types, S and T. The flatten method should take three parameters: a list, maybePairs of type List<ImmutablePair<Optional<S>, Optional<T>>>, an element defaultS of type S, and an element defaultT of type T. flatten should return a list of type List<ImmutablePair<S, T>> such that:
  • if an element s of type S is present as the first component of the pair at index i of maybePairs present, the first component of the pair at index i of the result list is s, otherwise it is defaultS;
  • if an element t of type T is present as the first component of the pair at index i of maybePairs present, the first component of the pair at index i of the result list is t, otherwise it is defaultT.

The idea is that the method flattens a list of pairs of optionals into a list of pairs, using the given default values wherever an empty optional appears.

Try to write this method using streams, rather than loops.

  1. Writing a main method Add a main method to Example that demonstrates your example methods in action on some example data.