I\'m porting a piece of code from .NET to Java and stumbled upon a scenario where I want to use stream to map & reduce.
class Content
{
private String
If you don't want to iterate 3 times over the list, or don't want to create too many Content intermediate objects, then you'd need to collect the stream with your own implementation:
public static Content collectToContent(Stream stream) {
return stream.collect(
Collector.of(
() -> new StringBuilder[] {
new StringBuilder(),
new StringBuilder(),
new StringBuilder() },
(StringBuilder[] arr, Content elem) -> {
arr[0].append(arr[0].length() == 0 ?
elem.getA() :
", " + elem.getA());
arr[1].append(arr[1].length() == 0 ?
elem.getB() :
", " + elem.getB());
arr[2].append(arr[2].length() == 0 ?
elem.getC() :
", " + elem.getC());
},
(arr1, arr2) -> {
arr1[0].append(arr1[0].length() == 0 ?
arr2[0].toString() :
arr2[0].length() == 0 ?
"" :
", " + arr2[0].toString());
arr1[1].append(arr1[1].length() == 0 ?
arr2[1].toString() :
arr2[1].length() == 0 ?
"" :
", " + arr2[1].toString());
arr1[2].append(arr1[2].length() == 0 ?
arr2[2].toString() :
arr2[2].length() == 0 ?
"" :
", " + arr2[2].toString());
return arr1;
},
arr -> new Content(
arr[0].toString(),
arr[1].toString(),
arr[2].toString())));
}
This collector first creates an array of 3 empty StringBuilder objects. Then defines an accumulator that appends each Contentelement's property to the corresponding StringBuilder. Then it defines a merge function that is only used when the stream is processed in parallel, which merges two previously accumulated partial results. Finally, it also defines a finisher function that transforms the 3 StringBuilder objects into a new instance of Content, with each property corresponding to the accumulated strings of the previous steps.
Please check Stream.collect() and Collector.of() javadocs for further reference.