I have a HashSet, I need to collect [0..n] elements in one HashSet and [n 1...l] elements in another HashSet using Java 8 streams. Where n >=0
is an arbitrary number, l >=0
is the length of given HashSet.
resultSet1 = set.stream()
.limit(n)
.collect(Collectors.toSet());
The above gives me [0..n] elements.
I could again call stream()
and then skip()
, but the thing is HashSet in java is unordered, so there is a probability that the skip method skips the element which was not collected above.
resultSet2 = set.stream()
.skip(n)
.collect(Collectors.toSet());
I can use traditional for
, but a solution using streams will be great.
E.g.
given set = {1,2,3,4,5}
resultSet1 = {1,2}
resultSet2 = {3,4,5}
CodePudding user response:
Here is a way to solve this problem
Set firstSet = set.stream()
.limit(n)
.collect(toSet());
Set secondSet = new HashSet<>(set);
secondSet.removeAll(firstSet);
A second way would be
AtomicInteger atomicInteger = new AtomicInteger();
Set<Integer> set = Set.of(1, 2, 3, 4, 5);
int n = 2;
Map<Boolean, Set<Integer>> map =
set.stream()
.collect(
Collectors.partitioningBy(
$ -> atomicInteger.addAndGet(1) > n),
Collectors.toSet()
);
CodePudding user response:
Use partitioningBy()
with a toSet()
downstream collector:
int[] i = {0}; // the array is "effectively final"
Map<Boolean, Set<Integer>> map = set.stream()
.collect(Collectors.partitioningBy(x -> i[0] < n, toSet()));
You can use a int[]
, which is effectively final, to hold the counter referenced within the lambda, which may mutate its contents.