Interleave elements in a stream with separator

后端 未结 2 1720
一个人的身影
一个人的身影 2021-01-11 17:42

Is there a nice way to use Java streams to interleave elements in a stream with a separator of the same type?

// Expected result in is list: [1, 0, 2, 0, 3]
         


        
2条回答
  •  爱一瞬间的悲伤
    2021-01-11 18:16

    You can do a similar thing which Collectors.joining does with Strings with a little helper method:

    static  Collector,List> intersperse(T delim) {
        return Collector.of(ArrayList::new, (l,e)-> {
            if(!l.isEmpty()) l.add(delim);
            l.add(e);
        }, (l,l2)-> {
            if(!l.isEmpty()) l.add(delim);
            l.addAll(l2);
            return l;
        });
    

    then you can use it similar to Collectors.joining(delimiter):

    List l=Stream.of(1, 2, 3).collect(intersperse(0));
    

    produces

    [1, 0, 2, 0, 3]

    Note that this is thread safe due to the way collect guards these operations.


    If you don’t want to collect into a list but insert the delimiters as an intermediate stream operation you can do it this way:

    Integer delimiter=0;
    Stream.of(1, 2, 3)/** or any other stream source */
          .map(Stream::of)
          .reduce((x,y)->Stream.concat(x, Stream.concat(Stream.of(delimiter), y)))
          .orElse(Stream.empty())
          /* arbitrary stream operations may follow */
    

提交回复
热议问题