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.
-
Immutable pair. Write a generic class,
ImmutablePair, with two generic parameters,SandTsay, that allows the construction of an (S,T) pair, and retrieval of its first and second components. OverridetoString()so that a pair is represented as a string of the form(string representation of first element,string representation of second element). -
Placeholder class. Create a class,
Example, to serve as a placeholder for the static methods you will write. -
Generic list concatenation Recall the
concatenatefunction 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 nothingInteger-specific about the notion of concatenating lists.Write a version of
concatenatethat is generic with respect to some typeT, and which takes a list of lists of typeList<List<T>>, and returns aList<T>that is the concatenation of these lists. -
Zip lists of different lengths Write a static method,
zip, that is generic with respect to two parameters,SandT, and that takes two parameters, a listfirstof typeList<S>and a listsecondof typeList<T>. The method should return a list of typeList<ImmutablePair<Optional<S>, Optional<T>>>. At each index i less than the minimum size offirstandsecond, the result should have a pair of present optionals corresponding to the elements at indices i offirstandsecond. At each index j (if any) at least the minimum size offirstandsecondand less than the maximum size offirstandsecond, 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.
- Flattening pairs of optionals Write a static method,
flatten, that is generic with respect to two types,SandT. Theflattenmethod should take three parameters: a list,maybePairsof typeList<ImmutablePair<Optional<S>, Optional<T>>>, an elementdefaultSof typeS, and an elementdefaultTof typeT.flattenshould return a list of typeList<ImmutablePair<S, T>>such that:
- if an element
sof typeSis present as the first component of the pair at index i ofmaybePairspresent, the first component of the pair at index i of the result list iss, otherwise it isdefaultS; - if an element
tof typeTis present as the first component of the pair at index i ofmaybePairspresent, the first component of the pair at index i of the result list ist, otherwise it isdefaultT.
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.
- Writing a main method Add a
mainmethod toExamplethat demonstrates your example methods in action on some example data.