In a class, Example
, write a static method, getSmallestCollection
. For any element type E
this method should accept a List
, collections
, of any type C
such that C
is a subtype of Collection<E>
(including Collection<E>
itself).
The return type of the method should be Optional<C>
. The method should return Optional.empty()
if collections
is an empty list. Otherwise, the method should return an optional containing one of the smallest elements of the list, as judged by the size()
method that is available on any subtype of Collection<E>
.
For example, if we have this list of sets available:
final Set<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3, 4));
final Set<Integer> s2 = new HashSet<>(Arrays.asList(1, 2));
final Set<Integer> s3 = new HashSet<>(Arrays.asList(1, 2, 3, 4));
final Set<Integer> s4 = new HashSet<>(Arrays.asList(3, 4));
final List<Set<Integer>> listOfSetsOfIntegers = Arrays.asList(s1, s2, s3, s4);
then doing:
final Optional<Set<Integer>> smallestSet = getSmallestCollection(listOfSetsOfIntegers);
should yield an optional that contains either s2
or s4
, as these are the joint-smallest sets in the list of sets.
Your implementation of getSmallestCollection
should be a one-liner that streams the list and performs an identity-free reduction.
Implement a main method that demonstrates your method in action on a list of sets of integers, and a list of lists of strings.
Hints: The real challenge here is to work out the right signature for the method getSmallestCollection
.
-
You might try to first implement:
static Optional<Collection<Integer>> getSmallestCollection(List<Collection<Integer>>) { ... }
to get your solution working for the explicit case of a list of collections of integers.
-
Then you could work out how to make the method work on lists of collections of some arbitrary type
E
. -
Finally, you could work out how to make the method work on a list of any subtype of
Collection<E>
(that's the hardest bit).