【问题标题】:pick 2 elements from stream at a time [duplicate]一次从流中选择2个元素[重复]
【发布时间】:2015-02-20 15:06:15
【问题描述】:

假设我们有一个集合(或流?)

{"1","2","3","4"...}

现在我们要取两个元素并像这样组成一对

{{"1","2"}, {"2","3"},{"3","4"}..}

我们知道如何以丑陋的方式做到这一点(for循环)。

我想知道我们如何使用 java 8 流来做到这一点?

因为 java 流和响应式扩展中的方法几乎相同(都是 monad),所以我认为可能有类似的 RX .pick(2) 会在 2 个元素到达时触发事件...

【问题讨论】:

标签: java java-8 java-stream


【解决方案1】:

它也不漂亮,但你可以用收藏家来做。我使用了一个 ArrayList,里面有 Arrays,但是如果你愿意,你可以使用不同的中间集合类型。

我在这里所做的是一个收集器,它将每个项目作为第二个项目添加到添加到累加器的最后一个数组中,并作为将添加到累加器的新数组的第一个项目。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

ArrayList<Integer[]> pairs =
    stream.collect(
        () -> new ArrayList<>(), 
        (acc, next) -> {
            if(acc.isEmpty()) {
                acc.add(new Integer[] {next, null});
            } else {
                acc.get(acc.size() - 1)[1] = next;
                acc.add(new Integer[] {next, null});
            }
        },
        ArrayList::addAll
    );

pairs.forEach(a -> System.out.println(a[0] + ", " + a[1]));

//-> 1, 2
//-> 2, 3
//-> 3, 4
//-> 4, 5
//-> 5, 6
//-> 6, null

【讨论】:

    【解决方案2】:

    可以使用IntStream.range 以流方式循环。

    String[] str = {"1", "2", "3", "4"};
    final String[][] result = IntStream.range(0, str.length - 1)
            .mapToObj(i -> new String[]{str[i], str[i + 1]})
            .toArray(String[][]::new);
    

    结果包含{{"1", "2"}, {"2", "3"}, {"3", "4"}}

    【讨论】:

    • 如果您从数组或其他索引集合中挑选元素,这很有效,但不适用于 Stream。
    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多