Consider a scenario where there is an object which contains the below member variables:
class Result{
private String message;
private boolean success;
}
After a query, we get a result set List.
Consider a scenario where there are 5 result set (instances of Result class): 3 out of the 5 instances have the success value as FALSE and TRUE for the rest 4. For example:
Row 1: success = false | message: failed for reason 1.
Row 2: success = true | message: success.
Row 3: success = false | message: failed for reason 2.
Row 4: success = false | message: failed for reason 3.
Row 5: success = true | message: success.
We need to group the result set in this particular way: Display the success = false rows at the top (in the same order that they were retrieved) and one grouped success message for all the rest rows.
So the output should be:
Row 1: success = false | message: failed for reason 1.
Row 2: success = false | message: failed for reason 2.
Row 3: success = false | message: failed for reason 3.
Row 4: success = true | message: success for the rest. (no need to display the same number of Rows for the success)
I tried for grouping the list based on success:
List<Result> resultSet;
Map<Boolean, List<Result>> result = resultset.stream().collect(Collectors.groupingBy(Result::success,Collectors.toList()));
But how to extract the message and also re-arrange the order by making Failed rows in the top and success row at the last
If you want a map you can use Collectors.partitioningBy which partitions using a boolean key.
Map<Boolean, List<Result>> result = resultSet.stream()
.collect(Collectors.partitioningBy(Result::getSuccess));
The above presumes you have a getter (here getSuccess) defined to return the success boolean.
Updated
Generate some test data.
record Result(String getMessage, boolean getSuccess) {
}
Random r = new Random();
Function<Integer, Result> createResult = rpw -> {
boolean b = r.nextBoolean();
return new Result((b
? "Row %2d: success = true | message: success.".formatted(row)
: "Row %2d: success = false | message: failed for reason %2d."
.formatted(row, r.nextInt(30) + 1)),
b);
};
List<Result> resultSet = IntStream.range(1, 15)
.mapToObj(createResult::apply).toList();
Now stream the test data and create a map of the results.
Map<Boolean, List<Result>> result = resultSet.stream()
.collect(Collectors.partitioningBy(Result::getSuccess));
Now print the map, first placing unsuccessful results on the stream and then placing a single success on the stream.
Stream.of(false, true).flatMap(b -> result.get(b).stream()
.map(Result::getMessage).limit(b ? 1 : Long.MAX_VALUE))
.forEach(System.out::println);
System.out.println("All other messages indicate success.");
prints something like this.
Row 2: success = false | message: failed for reason 15.
Row 3: success = false | message: failed for reason 5.
Row 5: success = false | message: failed for reason 12.
Row 7: success = false | message: failed for reason 25.
Row 9: success = false | message: failed for reason 10.
Row 10: success = false | message: failed for reason 23.
Row 14: success = false | message: failed for reason 24.
Row 1: success = true | message: success.
All other messages indicate success.
Or you can just print the unsuccessful messages.
result.get(false).forEach(res->System.out.println(res.getMessage));
System.out.println("All other messages indicate success.");
prints
Row 2: success = false | message: failed for reason 15.
Row 3: success = false | message: failed for reason 5.
Row 5: success = false | message: failed for reason 12.
Row 7: success = false | message: failed for reason 25.
Row 9: success = false | message: failed for reason 10.
Row 10: success = false | message: failed for reason 23.
Row 14: success = false | message: failed for reason 24.
All other messages indicate success.