如何将字符串流转换为字符串流对? [英] How can I convert a Stream of Strings to Stream of String pairs?

查看:384
本文介绍了如何将字符串流转换为字符串流对?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取一串字符串并将其转换为字对流。例如:

I want to take a stream of strings and turn it into a stream of word pairs. eg:

我有: {A,Apple,B,Banana,C,Carrot }

我想: {(A,Apple),(Apple,B ),(B,香蕉),(香蕉,C)}

这几乎是与Zipping相同,如使用Zipping流中所述JDK8 with lambda(java.util.stream.Streams.zip)

This is nearly the same as Zipping, as outlined at Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)

然而,这会产生:
{( A,Apple),(B,Banana),(C,Carrot)}

以下代码有效,但显然是错误的方式这样做(不是线程安全等等):

The following code works, but is clearly the wrong way to do it (not thread safe etc 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);});


推荐答案

如果您:


  1. 不喜欢用流中的所有字符串创建列表的想法

  2. 不想使用外部库

  3. 喜欢弄脏你的手

然后你可以创建一个方法来分组元素使用Java 8低级流构建器的流 StreamSupport Spliterator

Then you can create a method to group elements from a stream using Java 8 low-level stream builders StreamSupport and Spliterator:

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());
    }
}

方法和参数命名的灵感来自他们的Scala对应物。

Methods and parameters naming was inspired in their Scala counterparts.

让我们测试一下:

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




[[A,Apple],[Apple,B],[ B,香蕉],[香蕉,C],[C,胡萝卜]]

[[A, Apple], [Apple, B], [B, Banana], [Banana, C], [C, Carrot]]

如何不重复元素:

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




[[A,Apple],[B,Banana],[ C,Carrot]]

[[A, Apple], [B, Banana], [C, Carrot]]

现在有了无限的 Stream

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




[0,1,2,3,4]

[1,2,3,4,5]

[2,3,4,5,6]

[3,4,5,6,7] ]

[4,5,6,7,8]

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

这篇关于如何将字符串流转换为字符串流对?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆