@ Eugene answer is sweet because Guava is sweet. But if you do not have Guava in your class path, here is another way:
List<Set<Integer>> list = block.stream() .flatMap(Set::stream) .sorted() .collect(partitioning(3));
Firstly, I collect all the sets into a single stream, then sort all the elements and finally collect the entire sorted stream into a list of sets. To do this, I call a helper method that uses a custom collector:
private static <T> Collector<T, ?, List<Set<T>>> partitioning(int size) { class Acc { int count = 0; List<Set<T>> list = new ArrayList<>(); void add(T elem) { int index = count++ / size; if (index == list.size()) list.add(new LinkedHashSet<>()); list.get(index).add(elem); } Acc merge(Acc another) { another.list.stream().flatMap(Set::stream).forEach(this::add); return this; } } return Collector.of(Acc::new, Acc::add, Acc::merge, acc -> acc.list); }
The method gets the size of each section and uses the local Acc class as a mutable structure that will be used by the collector. Inside the Acc class, I use a List that will contain instances of LinkedHashSet that will contain the elements of the stream.
The Acc class contains an account of all the elements that are already assembled. In the add method, I calculate the index of the list and increase it, and if there was no set at that position in the list, I add a new empty LinkedHashSet to it. Then I add the item to the set.
Since I call sorted() on the stream to sort its elements before collecting, I need to use data structures that preserve the insertion order. This is why I use ArrayList for the external list and LinkedHashSet for the internal sets.
The merge method must be used by parallel threads to combine two previously accumulated Acc instances. I simply add all the elements of the resulting Acc instance to this Acc instance by delegating the add method.
Finally, I use Collector.of to create a collector based on the methods of the Acc class. The final argument is the finisher function, which simply returns a list of Acc instances.
Federico peralta schaffner
source share