Java – how to convert a character stream to a string stream pair?

I want to take a string and convert it into a word stream For example:

I have: {"a", "apple", "B", "banana", "C", "carrot"}

I want: {("a", "apple"), ("apple", "B"), ("B", "banana"), ("banana", "C")}

This is almost the same as zipping, as described in zipping streams using jdk8 with lambda (Java. Util. Stream. Streams. Zip)

However, this will produce: {(a, Apple), (B, banana), (C, carrot)}

The following code is valid, but obviously the wrong method (not thread safe, etc.):

static String buffered = null;

static void output(String s) {
    String result = null;
    if (buffered != null) {
        result = buffered + "," + s;
    } else {
        result = null;
    }

    buffered = s;
    System.out.println(result);
}

// ***** 

Stream<String> testing = Stream.of("A","Apple","B","Banana","C","Carrot");
testing.forEach(s -> {output(s);});

Solution

If you:

>Don't like the idea of creating a list of all strings in the stream > don't want to use external libraries > like to dirty your hands

You can then use the Java 8 low-level flow builder streamsupport and splitter to create a way to group elements from the flow:

class StreamUtils {
    public static<T> Stream<List<T>> sliding(int size,Stream<T> stream) {
        return sliding(size,1,stream);
    }

    public static<T> Stream<List<T>> sliding(int size,int step,Stream<T> stream) {
        Spliterator<T> spliterator = stream.spliterator();
        long estimateSize;

        if (!spliterator.hascharacteristics(Spliterator.SIZED)) {
            estimateSize = Long.MAX_VALUE;
        } else if (size > spliterator.estimateSize()) {
            estimateSize = 0;
        } else {
            estimateSize = (spliterator.estimateSize() - size) / step + 1;
        }

        return StreamSupport.stream(
                new Spliterators.AbstractSpliterator<List<T>>(estimateSize,spliterator.characteristics()) {
                    List<T> buffer = new ArrayList<>(size);

                    @Override
                    public boolean tryAdvance(Consumer<? super List<T>> consumer) {
                        while (buffer.size() < size && spliterator.tryAdvance(buffer::add)) {
                            // Nothing to do
                        }

                        if (buffer.size() == size) {
                            List<T> keep = new ArrayList<>(buffer.subList(step,size));
                            consumer.accept(buffer);
                            buffer = keep;
                            return true;
                        }
                        return false;
                    }
                },stream.isParallel());
    }
}

Methods and parameter naming are inspired by their Scala counterparts

Let's test:

Stream<String> testing = Stream.of("A","Carrot");
System.out.println(StreamUtils.sliding(2,testing).collect(Collectors.toList()));

How about not repeating elements:

Stream<String> testing = Stream.of("A",2,Carrot]]

现在有一个无限的流:

StreamUtils.sliding(5,Stream.iterate(0,n -> n + 1))
        .limit(5)
        .forEach(System.out::println);

[0,3,4] [1,4,5] [2,5,6] [3,6,7] [4,7,8]

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>