Java 8 stream join and return multiple values

后端 未结 4 1408
时光说笑
时光说笑 2020-12-17 22:32

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          


        
4条回答
  •  再見小時候
    2020-12-17 23:01

    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.

提交回复
热议问题